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; }
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 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 audiodsp_get_audioinfo(struct audiodsp_priv *priv) { int ret = -1; int audio_info = 0; audio_info = DSP_RD(DSP_AUDIO_FORMAT_INFO); if(priv->frame_format.valid == (CHANNEL_VALID|DATA_WIDTH_VALID|SAMPLE_RATE_VALID)){ ret = 0; goto exit; } else if(audio_info){ priv->frame_format.channel_num = audio_info&0xf; if(priv->frame_format.channel_num) priv->frame_format.valid |= CHANNEL_VALID; priv->frame_format.data_width= (audio_info>>4)&0x3f; if(priv->frame_format.data_width) priv->frame_format.valid |= DATA_WIDTH_VALID; priv->frame_format.sample_rate = (audio_info>>10); if(priv->frame_format.sample_rate) priv->frame_format.valid |= SAMPLE_RATE_VALID; ret = 0; } if(ret == 0){ DSP_PRNT(" audiodsp got audioinfo:[ch num %d],[sr %d]", \ priv->frame_format.channel_num,priv->frame_format.sample_rate); } exit: return ret; }
static void audiodsp_monitor(unsigned long arg) { struct audiodsp_priv *priv=(struct audiodsp_priv *)arg; static unsigned long old_dsp_jiffies=0; static unsigned long jiffies_error=0; unsigned long dsp_jiffies; unsigned long dsp_status; dsp_jiffies=DSP_RD(DSP_JIFFIES); dsp_status=DSP_RD(DSP_STATUS); if(old_dsp_jiffies==dsp_jiffies) jiffies_error++; else { jiffies_error=0; old_dsp_jiffies=dsp_jiffies; } if(jiffies_error>5) { DSP_PRNT("Found audio dsp have some problem not running \n"); DSP_PRNT("audio jiffies=%ld\n",old_dsp_jiffies); DSP_PRNT("audio status=%lx\n",dsp_status); } if(!dsp_check_status(priv) ){ priv->dsp_abnormal_count++; } else priv->dsp_abnormal_count = 0; if(priv->dsp_abnormal_count > 5 || jiffies_error > 5){ priv->decode_fatal_err |= 0x2; priv->dsp_abnormal_count = 0; jiffies_error = 0; } priv->dsp_mointer.expires=jiffies+HZ; add_timer(&priv->dsp_mointer); }
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); }
void dsp_c_entry(void ) { #if 0 while(stop); #ifndef __ARC600__ if(DSP_RD(DSP_STATUS)==DSP_STATUS_RUNING) {/*halt the dsp */ printk("audio dsp halted now\n"); dsp_flush_printk_data(); DSP_WD(DSP_STATUS,DSP_STATUS_HALT); arch_halt(); } else #endif { DSP_WD(DSP_STATUS,DSP_STATUS_RUNING); } printk("DSP version=%s,dsp clock %d\n",firmware_version,get_system_clk()); #if defined(ENABLE_EFUSE) || defined(ENABLE_FIRMWARE_ENCRYPT) /*add by jeff begin*/ add_data(); #endif DSP_WD(DSP_JIFFIES,0); dsp_memory_init(); #endif dsp_irq_init(); #if 0 dsp_timer_init(); dsp_cache_init(1); dsp_mailbox_init(); #endif dsp_irq_enable(); #if 0 init_device(); #endif start_system(); while(1) { //arch_sleep(); //test_arc_run++; dsp_main(); } }
int dsp_check_status(struct audiodsp_priv *priv) { unsigned dsp_halt_score = 0; unsigned ablevel = 0; int pcmlevel = 0; if(DSP_RD(DSP_STATUS) != DSP_STATUS_RUNING) return 1; ablevel =READ_MPEG_REG(AIU_MEM_AIFIFO_LEVEL); pcmlevel = dsp_codec_get_bufer_data_len(priv); if((ablevel == priv->last_ablevel && ablevel > 50*1024)&& \ (pcmlevel == priv->last_pcmlevel && pcmlevel < 512)){ priv->last_ablevel = ablevel; priv->last_pcmlevel = pcmlevel; printk("dsp not working ............\n"); return 0; } priv->last_ablevel = ablevel; priv->last_pcmlevel = pcmlevel; return 1; }
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; }
unsigned long stream_buffer_end; unsigned long stream_buffer_size; unsigned long user_read_offset; //the offset of the stream buffer which user space reading }priv_data_t; static priv_data_t priv_data = {0}; static ssize_t pcmenc_ptr_show(struct class* class, struct class_attribute* attr, char* buf) { ssize_t ret = 0; ret = sprintf(buf, "pcmenc runtime info:\n" " pcmenc rd ptr :\t%x\n" " pcmenc wr ptr :\t%x\n" " pcmenc level :\t%x\n", (DSP_RD(DSP_DECODE_51PCM_OUT_RD_ADDR)), (DSP_RD(DSP_DECODE_51PCM_OUT_WD_ADDR)), pcmenc_stream_content() ); return ret; } static struct class_attribute pcmenc_attrs[]={ __ATTR_RO(pcmenc_ptr), __ATTR_NULL }; static void create_pcmenc_attrs(struct class* class) { int i=0; for(i=0; pcmenc_attrs[i].attr.name; i++){ class_create_file(class, &pcmenc_attrs[i]); }
u32 dsp_codec_get_current_pts(struct audiodsp_priv *priv) { #ifdef CONFIG_AM_PTSSERVER u32 pts; u32 delay_pts; int len; u64 frame_nums; int res; u32 offset, buffered_len, wp; mutex_lock(&priv->stream_buffer_mutex); if (priv->frame_format.channel_num == 0 || priv->frame_format.sample_rate == 0 || priv->frame_format.data_width == 0) { printk("unvalid audio format!\n"); mutex_unlock(&priv->stream_buffer_mutex); return -1; } #if 0 if (priv->stream_fmt == MCODEC_FMT_COOK) { pts = priv->cur_frame_info.offset; mutex_unlock(&priv->stream_buffer_mutex); } else #endif { buffered_len = DSP_RD(DSP_BUFFERED_LEN); wp = DSP_RD(DSP_DECODE_OUT_WD_PTR); offset = DSP_RD(DSP_AFIFO_RD_OFFSET1); // before audio start, the pts always be at the first index if(!timestamp_apts_started()){ offset = 0; } if (priv->stream_fmt == MCODEC_FMT_COOK || priv->stream_fmt == MCODEC_FMT_RAAC) { pts = DSP_RD(DSP_AFIFO_RD_OFFSET1); res = 0; } else { res = pts_lookup_offset(PTS_TYPE_AUDIO, offset, &pts, 300); //printk("pts_lookup_offset = %d, buffer_len = %d, res = %d\n", offset, buffered_len, res); if (!priv->first_lookup_over) { priv->first_lookup_over = 1; if (first_lookup_pts_failed(PTS_TYPE_AUDIO)) { priv->out_len_after_last_valid_pts = 0; priv->last_valid_pts = pts; mutex_unlock(&priv->stream_buffer_mutex); return pts; } } } if (res == 0) { //printk("check out pts == %x\n", pts); priv->out_len_after_last_valid_pts = 0; len = buffered_len + dsp_codec_get_bufer_data_len1(priv, wp); frame_nums = (len * 8 / (priv->frame_format.data_width * priv->frame_format.channel_num)); delay_pts = div64_u64(frame_nums*90*20, priv->frame_format.sample_rate/50); //printk("cal delay pts == %x\n", delay_pts); if (pts > delay_pts) { pts -= delay_pts; } else { pts = 0; } priv->last_valid_pts = pts; //printk("len = %d, data_width = %d, channel_num = %d, frame_nums = %lld, sample_rate = %d, pts = %d\n", // len, priv->frame_format.data_width,priv->frame_format.channel_num, frame_nums, priv->frame_format.sample_rate, pts); } else if (priv->last_valid_pts >= 0) { pts = priv->last_valid_pts; len = priv->out_len_after_last_valid_pts; frame_nums = (len * 8 / (priv->frame_format.data_width * priv->frame_format.channel_num)); pts += div64_u64(frame_nums*90*20, priv->frame_format.sample_rate/50); //printk("last_pts = %d, len = %d, data_width = %d, channel_num = %d, frame_nums = %lld, sample_rate = %d, pts = %d\n", // priv->last_valid_pts, len, priv->frame_format.data_width,priv->frame_format.channel_num, frame_nums, priv->frame_format.sample_rate, pts); } else { printk("checkout audio pts failed!\n"); pts = -1; } mutex_unlock(&priv->stream_buffer_mutex); } return pts; #endif return -1; }
static int audiodsp_ioctl(struct inode *node, struct file *file, unsigned int cmd, unsigned long args) { struct audiodsp_priv *priv=audiodsp_privdata(); struct audiodsp_cmd *a_cmd; char name[64]; int len; unsigned long pts; int ret=0; unsigned long *val=(unsigned long *)args; #ifdef ENABLE_WAIT_FORMAT static int wait_format_times=0; #endif switch(cmd) { case AUDIODSP_SET_FMT: priv->stream_fmt=args; if(args == MCODEC_FMT_DTS) IEC958_mode_codec = 1; else if(args == MCODEC_FMT_AC3) IEC958_mode_codec = 2; else IEC958_mode_codec = 0; break; case AUDIODSP_START: if(IEC958_mode_raw_last != IEC958_mode_raw || IEC958_mode_codec_last != IEC958_mode_codec) { IEC958_mode_raw_last = IEC958_mode_raw; IEC958_mode_codec_last = IEC958_mode_codec; aml_alsa_hw_reprepare(); } priv->decoded_nb_frames = 0; priv->format_wait_count = 0; if(priv->stream_fmt<=0) { DSP_PRNT("Audio dsp steam format have not set!\n"); } else { ret=audiodsp_start(); } break; case AUDIODSP_STOP: //DSP_PRNT("audiodsp command stop\n"); stop_audiodsp_monitor(priv); dsp_stop(priv); priv->decoded_nb_frames = 0; priv->format_wait_count = 0; break; #ifdef ENABLE_WAIT_FORMAT case AUDIODSP_DECODE_START: if(priv->dsp_is_started) { dsp_codec_start(priv); wait_format_times=0; } else { DSP_PRNT("Audio dsp have not started\n"); } break; case AUDIODSP_WAIT_FORMAT: if(priv->dsp_is_started) { struct audio_info *audio_format; int ch = 0; audio_format = get_audio_info(); wait_format_times++; if(wait_format_times>100){ int audio_info = DSP_RD(DSP_AUDIO_FORMAT_INFO); if(audio_info){ priv->frame_format.channel_num = audio_info&0xf; if(priv->frame_format.channel_num) priv->frame_format.valid |= CHANNEL_VALID; priv->frame_format.data_width= (audio_info>>4)&0x3f; if(priv->frame_format.data_width) priv->frame_format.valid |= DATA_WIDTH_VALID; priv->frame_format.sample_rate = (audio_info>>10); if(priv->frame_format.sample_rate) priv->frame_format.valid |= SAMPLE_RATE_VALID; DSP_PRNT("warning::got info from mailbox failed,read from regiser\n"); ret = 0; }else{ DSP_PRNT("dsp have not set the codec stream's format details,valid=%x\n", priv->frame_format.valid); priv->format_wait_count++; if(priv->format_wait_count > 5){ if(audio_format->channels&&audio_format->sample_rate){ priv->frame_format.channel_num = audio_format->channels>2?2:audio_format->channels; priv->frame_format.sample_rate = audio_format->sample_rate; priv->frame_format.data_width = 16; priv->frame_format.valid = CHANNEL_VALID|DATA_WIDTH_VALID|SAMPLE_RATE_VALID; DSP_PRNT("we have not got format details from dsp,so use the info got from the header parsed instead\n"); ret = 0; }else{ ret = -1; } }else{ ret=-1; } } }else if(priv->frame_format.valid == (CHANNEL_VALID|DATA_WIDTH_VALID|SAMPLE_RATE_VALID)){
static irqreturn_t audiodsp_mailbox_irq(int irq, void *data) { struct audiodsp_priv *priv=(struct audiodsp_priv *)data; unsigned long status; struct mail_msg msg; int i = 0; #if MESON_CPU_TYPE < MESON_CPU_TYPE_MESON8 unsigned long fiq_mask; #endif status=READ_VREG(MB1_REG); #if MESON_CPU_TYPE < MESON_CPU_TYPE_MESON8 fiq_mask=READ_VREG(MB1_SEL); status=status&fiq_mask; #endif if(status&(1<<M1B_IRQ0_PRINT)) { get_mailbox_data(priv,M1B_IRQ0_PRINT,&msg); SYS_CLEAR_IRQ(M1B_IRQ0_PRINT); // inv_dcache_range((unsigned long )msg.data,(unsigned long)msg.data+msg.len); DSP_PRNT("%s", msg.data); //audiodsp_work.buf = msg.data; //schedule_work(&audiodsp_work.audiodsp_workqueue); } if(status&(1<<M1B_IRQ1_BUF_OVERFLOW)) { SYS_CLEAR_IRQ(M1B_IRQ1_BUF_OVERFLOW); DSP_PRNT("DSP BUF over flow\n"); } if(status&(1<<M1B_IRQ2_BUF_UNDERFLOW)) { SYS_CLEAR_IRQ(M1B_IRQ2_BUF_UNDERFLOW); DSP_PRNT("DSP BUF over flow\n"); } if(status&(1<<M1B_IRQ3_DECODE_ERROR)) { SYS_CLEAR_IRQ(M1B_IRQ3_DECODE_ERROR); priv->decode_error_count++; } if(status&(1<<M1B_IRQ4_DECODE_FINISH_FRAME)) { struct frame_info *info; SYS_CLEAR_IRQ(M1B_IRQ4_DECODE_FINISH_FRAME); get_mailbox_data(priv,M1B_IRQ4_DECODE_FINISH_FRAME,&msg); info=(struct frame_info *)msg.data; if(info!=NULL) { priv->cur_frame_info.offset=info->offset; priv->cur_frame_info.buffered_len=info->buffered_len; } priv->decoded_nb_frames ++; complete(&priv->decode_completion); } if(status& (1<<M1B_IRQ5_STREAM_FMT_CHANGED)) { struct frame_fmt *fmt; SYS_CLEAR_IRQ(M1B_IRQ5_STREAM_FMT_CHANGED); get_mailbox_data(priv,M1B_IRQ5_STREAM_FMT_CHANGED,&msg); fmt=(void *)msg.data; //DSP_PRNT("frame format changed"); if(fmt==NULL || (sizeof(struct frame_fmt )<msg.len)) { DSP_PRNT("frame format message error\n"); } else { DSP_PRNT("frame format changed,fmt->valid 0x%x\n",fmt->valid); if(fmt->valid&SUB_FMT_VALID) { priv->frame_format.sub_fmt=fmt->sub_fmt; priv->frame_format.valid|=SUB_FMT_VALID; } if(fmt->valid&CHANNEL_VALID) { priv->frame_format.channel_num=((fmt->channel_num > 2) ? 2 : (fmt->channel_num)); priv->frame_format.valid|=CHANNEL_VALID; } if(fmt->valid&SAMPLE_RATE_VALID) { priv->frame_format.sample_rate=fmt->sample_rate; priv->frame_format.valid|=SAMPLE_RATE_VALID; } if(fmt->valid&DATA_WIDTH_VALID) { priv->frame_format.data_width=fmt->data_width; priv->frame_format.valid|=DATA_WIDTH_VALID; } } /* if(fmt->data.pcm_encoded_info){ set_pcminfo_data(fmt->data.pcm_encoded_info); } */ DSP_PRNT("audio info from dsp:sample_rate=%d channel_num=%d\n",priv->frame_format.sample_rate,priv->frame_format.channel_num); } if(status & (1<<M1B_IRQ8_IEC958_INFO)){ struct digit_raw_output_info* info; SYS_CLEAR_IRQ(M1B_IRQ8_IEC958_INFO); get_mailbox_data(priv, M1B_IRQ8_IEC958_INFO, &msg); info = (void*)msg.data; #if 1 IEC958_bpf = info->bpf; IEC958_brst = info->brst; IEC958_length = info->length; IEC958_padsize = info->padsize; IEC958_mode = info->mode; IEC958_syncword1 = info->syncword1; IEC958_syncword2 = info->syncword2; IEC958_syncword3 = info->syncword3; IEC958_syncword1_mask = info->syncword1_mask; IEC958_syncword2_mask = info->syncword2_mask; IEC958_syncword3_mask = info->syncword3_mask; IEC958_chstat0_l = info->chstat0_l; IEC958_chstat0_r = info->chstat0_r; IEC958_chstat1_l = info->chstat1_l; IEC958_chstat1_r = info->chstat1_r; #endif // IEC958_mode_codec = info->can_bypass; DSP_PRNT( "MAILBOX: got IEC958 info\n"); //schedule_work(&audiodsp_work.audiodsp_workqueue); } if(status& (1<<M1B_IRQ5_STREAM_RD_WD_TEST)){ DSP_WD((0x84100000-4096+20*20),0); SYS_CLEAR_IRQ(M1B_IRQ5_STREAM_RD_WD_TEST); get_mailbox_data(priv,M1B_IRQ5_STREAM_RD_WD_TEST,&msg); for(i = 0;i<12;i++){ if((DSP_RD((0x84100000-512*1024+i*20)))!= (0xff00|i)){ DSP_PRNT("a9 read dsp reg error ,now 0x%lx, should be 0x%x \n",(DSP_RD((0x84100000-512*1024+i*20))),12-i); } // DSP_PRNT("A9 audio dsp reg%d value 0x%x\n",i,DSP_RD((0x84100000-4096+i*20))); } for(i = 0;i<12;i++){ DSP_WD((0x84100000-512*1024+i*20),(i%2)?i:(0xf0|i)); } DSP_WD((0x84100000-512*1024+20*20),DSP_STATUS_HALT); // DSP_PRNT("A9 mail box handle finished\n"); // dsp_mailbox_send(priv, 1, M1B_IRQ5_STREAM_RD_WD_TEST, 0, NULL,0); } if(status & (1<<M1B_IRQ7_DECODE_FATAL_ERR)){ int err_code; SYS_CLEAR_IRQ(M1B_IRQ7_DECODE_FATAL_ERR); get_mailbox_data(priv,M1B_IRQ7_DECODE_FATAL_ERR,&msg); err_code = msg.cmd; priv->decode_fatal_err = err_code; if(err_code & 0x01){ timestamp_pcrscr_set(timestamp_vpts_get()); timestamp_pcrscr_enable(1); } else if(err_code & 0x02){ printk("Set decode_fatal_err flag, Reset audiodsp!\n"); } } return 0; }