void rmparser_release(void) { WRITE_MPEG_REG(PARSER_INT_ENABLE, 0); free_irq(INT_PARSER, (void *)rmparser_id); #ifdef MANAGE_PTS pts_stop(PTS_TYPE_VIDEO); pts_stop(PTS_TYPE_AUDIO); #endif return; }
void esparser_release(struct stream_buf_s *buf) { u32 pts_type; /* check if esparser_init() is ever called */ if ((buf->flag & BUF_FLAG_PARSER) == 0) { return; } if (atomic_dec_and_test(&esparser_use_count)) { WRITE_MPEG_REG(PARSER_INT_ENABLE, 0); free_irq(INT_PARSER, (void *)esparser_id); if (search_pattern) { dma_unmap_single(NULL, search_pattern_map, SEARCH_PATTERN_LEN, DMA_TO_DEVICE); kfree(search_pattern); search_pattern = NULL; } } if (buf->type == BUF_TYPE_VIDEO) { pts_type = PTS_TYPE_VIDEO; } else if (buf->type == BUF_TYPE_AUDIO) { pts_type = PTS_TYPE_AUDIO; } else if (buf->type == BUF_TYPE_SUBTITLE) { buf->flag &= ~BUF_FLAG_PARSER; return; } else { return; } buf->flag &= ~BUF_FLAG_PARSER; pts_stop(pts_type); }
void tsdemux_release(void) { pcrscr_valid=0; first_pcr=0; WRITE_MPEG_REG(PARSER_INT_ENABLE, 0); WRITE_MPEG_REG(PARSER_VIDEO_HOLE, 0); WRITE_MPEG_REG(PARSER_AUDIO_HOLE, 0); free_irq(INT_PARSER, (void *)tsdemux_fetch_id); #ifndef ENABLE_DEMUX_DRIVER WRITE_MPEG_REG(STB_INT_MASK, 0); free_irq(INT_DEMUX, (void *)tsdemux_irq_id); #else tsdemux_set_aid(0xffff); tsdemux_set_vid(0xffff); tsdemux_set_sid(0xffff); tsdemux_set_pcrid(0xffff); tsdemux_free_irq(); curr_vid_id = 0xffff; curr_aud_id = 0xffff; curr_sub_id = 0xffff; curr_pcr_id = 0xffff; curr_pcr_num = 0xffff; #endif pts_stop(PTS_TYPE_VIDEO); pts_stop(PTS_TYPE_AUDIO); #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 switch_mod_gate_by_type(MOD_DEMUX, 0); #endif }
s32 tsdemux_init(u32 vid, u32 aid, u32 sid, u32 pcrid, bool is_hevc) { s32 r; u32 parser_sub_start_ptr; u32 parser_sub_end_ptr; u32 parser_sub_rp; #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 switch_mod_gate_by_type(MOD_DEMUX, 1); #endif parser_sub_start_ptr = READ_MPEG_REG(PARSER_SUB_START_PTR); parser_sub_end_ptr = READ_MPEG_REG(PARSER_SUB_END_PTR); parser_sub_rp = READ_MPEG_REG(PARSER_SUB_RP); WRITE_MPEG_REG(RESET1_REGISTER, RESET_PARSER); #ifdef ENABLE_DEMUX_DRIVER tsdemux_reset(); #else WRITE_MPEG_REG(RESET1_REGISTER, RESET_PARSER | RESET_DEMUXSTB); WRITE_MPEG_REG(STB_TOP_CONFIG, 0); WRITE_MPEG_REG(DEMUX_CONTROL, 0); #endif /* set PID filter */ printk("tsdemux video_pid = 0x%x, audio_pid = 0x%x, sub_pid = 0x%x, pcrid = 0x%x\n", vid, aid, sid, pcr_pid); #ifndef ENABLE_DEMUX_DRIVER WRITE_MPEG_REG(FM_WR_DATA, (((vid & 0x1fff) | (VIDEO_PACKET << 13)) << 16) | ((aid & 0x1fff) | (AUDIO_PACKET << 13))); WRITE_MPEG_REG(FM_WR_ADDR, 0x8000); while (READ_MPEG_REG(FM_WR_ADDR) & 0x8000) { ; } WRITE_MPEG_REG(FM_WR_DATA, (((sid & 0x1fff) | (SUB_PACKET << 13)) << 16) | 0xffff); WRITE_MPEG_REG(FM_WR_ADDR, 0x8001); while (READ_MPEG_REG(FM_WR_ADDR) & 0x8000) { ; } WRITE_MPEG_REG(MAX_FM_COMP_ADDR, 1); WRITE_MPEG_REG(STB_INT_MASK, 0); WRITE_MPEG_REG(STB_INT_STATUS, 0xffff); /* TS data path */ WRITE_MPEG_REG(FEC_INPUT_CONTROL, 0x7000); WRITE_MPEG_REG(DEMUX_MEM_REQ_EN, (1 << VIDEO_PACKET) | (1 << AUDIO_PACKET) | (1 << SUB_PACKET)); WRITE_MPEG_REG(DEMUX_ENDIAN, (7 << OTHER_ENDIAN) | (7 << BYPASS_ENDIAN) | (0 << SECTION_ENDIAN)); WRITE_MPEG_REG(TS_HIU_CTL, 1 << USE_HI_BSF_INTERFACE); WRITE_MPEG_REG(TS_FILE_CONFIG, (demux_skipbyte << 16) | (6 << DES_OUT_DLY) | (3 << TRANSPORT_SCRAMBLING_CONTROL_ODD) | (1 << TS_HIU_ENABLE) | (4 << FEC_FILE_CLK_DIV)); /* enable TS demux */ WRITE_MPEG_REG(DEMUX_CONTROL, (1 << STB_DEMUX_ENABLE) | (1 << KEEP_DUPLICATE_PACKAGE)); #endif if (fetchbuf == 0) { printk("%s: no fetchbuf\n", __FUNCTION__); return -ENOMEM; } /* hook stream buffer with PARSER */ #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 if (HAS_HEVC_VDEC && is_hevc) { WRITE_MPEG_REG(PARSER_VIDEO_START_PTR, READ_VREG(HEVC_STREAM_START_ADDR)); WRITE_MPEG_REG(PARSER_VIDEO_END_PTR, READ_VREG(HEVC_STREAM_END_ADDR) - 8); CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_VID_MAN_RD_PTR); WRITE_VREG(DOS_GEN_CTRL0, 3<<1); // set vififo_vbuf_rp_sel=>hevc SET_VREG_MASK(HEVC_STREAM_CONTROL, (1<<3)|(0<<4)); // set use_parser_vbuf_wp SET_VREG_MASK(HEVC_STREAM_CONTROL, 1); // set stream_fetch_enable SET_VREG_MASK(HEVC_STREAM_FIFO_CTL, (1<<29)); // set stream_buffer_hole with 256 bytes } else #endif { WRITE_MPEG_REG(PARSER_VIDEO_START_PTR, READ_VREG(VLD_MEM_VIFIFO_START_PTR)); WRITE_MPEG_REG(PARSER_VIDEO_END_PTR, READ_VREG(VLD_MEM_VIFIFO_END_PTR)); CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_VID_MAN_RD_PTR); WRITE_VREG(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); CLEAR_VREG_MASK(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); if (HAS_HEVC_VDEC) { WRITE_VREG(DOS_GEN_CTRL0, 0); // set vififo_vbuf_rp_sel=>vdec } } WRITE_MPEG_REG(PARSER_AUDIO_START_PTR, READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); WRITE_MPEG_REG(PARSER_AUDIO_END_PTR, READ_MPEG_REG(AIU_MEM_AIFIFO_END_PTR)); CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_AUD_MAN_RD_PTR); WRITE_MPEG_REG(PARSER_CONFIG, (10 << PS_CFG_PFIFO_EMPTY_CNT_BIT) | (1 << PS_CFG_MAX_ES_WR_CYCLE_BIT) | (16 << PS_CFG_MAX_FETCH_CYCLE_BIT)); WRITE_MPEG_REG(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); CLEAR_MPEG_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); WRITE_MPEG_REG(PARSER_SUB_START_PTR, parser_sub_start_ptr); WRITE_MPEG_REG(PARSER_SUB_END_PTR, parser_sub_end_ptr); WRITE_MPEG_REG(PARSER_SUB_RP, parser_sub_rp); SET_MPEG_REG_MASK(PARSER_ES_CONTROL, (7 << ES_SUB_WR_ENDIAN_BIT) | ES_SUB_MAN_RD_PTR); #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 if (HAS_HEVC_VDEC) r = pts_start((is_hevc) ? PTS_TYPE_HEVC : PTS_TYPE_VIDEO); else #endif r = pts_start(PTS_TYPE_VIDEO); if (r < 0) { printk("Video pts start failed.(%d)\n", r); goto err1; } if ((r = pts_start(PTS_TYPE_AUDIO)) < 0) { printk("Audio pts start failed.(%d)\n", r); goto err2; } r = request_irq(INT_PARSER, parser_isr, IRQF_SHARED, "tsdemux-fetch", (void *)tsdemux_fetch_id); if (r) { goto err3; } WRITE_MPEG_REG(PARSER_INT_STATUS, 0xffff); WRITE_MPEG_REG(PARSER_INT_ENABLE, PARSER_INTSTAT_FETCH_CMD << PARSER_INT_HOST_EN_BIT); WRITE_MPEG_REG(PARSER_VIDEO_HOLE, 0x400); WRITE_MPEG_REG(PARSER_AUDIO_HOLE, 0x400); discontinued_counter = 0; #ifndef ENABLE_DEMUX_DRIVER r = request_irq(INT_DEMUX, tsdemux_isr, IRQF_SHARED, "tsdemux-irq", (void *)tsdemux_irq_id); WRITE_MPEG_REG(STB_INT_MASK, (1 << SUB_PES_READY) | (1 << NEW_PDTS_READY) | (1 << DIS_CONTINUITY_PACKET)); if (r) { goto err4; } #else tsdemux_config(); tsdemux_request_irq(tsdemux_isr, (void *)tsdemux_irq_id); if (vid < 0x1FFF) { curr_vid_id = vid; tsdemux_set_vid(vid); } if (aid < 0x1FFF) { curr_aud_id = aid; tsdemux_set_aid(aid); } if (sid < 0x1FFF) { curr_sub_id = sid; tsdemux_set_sid(sid); } curr_pcr_id = pcr_pid; if ((pcr_pid < 0x1FFF) && (pcr_pid != vid) && (pcr_pid != aid) && (pcr_pid != sid)) { tsdemux_set_pcrid(pcr_pid); } #endif reset_pcr_regs(); first_pcr = 0; pcrscr_valid=1; return 0; #ifndef ENABLE_DEMUX_DRIVER err4: free_irq(INT_PARSER, (void *)tsdemux_fetch_id); #endif err3: pts_stop(PTS_TYPE_AUDIO); err2: #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 if (HAS_HEVC_VDEC) pts_stop((is_hevc) ? PTS_TYPE_HEVC : PTS_TYPE_VIDEO); else #endif pts_stop(PTS_TYPE_VIDEO); err1: printk("TS Demux init failed.\n"); return -ENOENT; }
s32 esparser_init(struct stream_buf_s *buf) { s32 r; u32 pts_type; u32 parser_sub_start_ptr; u32 parser_sub_end_ptr; u32 parser_sub_rp; bool first_use = false; #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 if (HAS_HEVC_VDEC && (buf->type == BUF_TYPE_HEVC)) { pts_type = PTS_TYPE_HEVC; } else #endif if (buf->type == BUF_TYPE_VIDEO) { pts_type = PTS_TYPE_VIDEO; } else if (buf->type & BUF_TYPE_AUDIO) { pts_type = PTS_TYPE_AUDIO; } else if (buf->type & BUF_TYPE_SUBTITLE) { pts_type = PTS_TYPE_MAX; } else { return -EINVAL; } parser_sub_start_ptr = READ_MPEG_REG(PARSER_SUB_START_PTR); parser_sub_end_ptr = READ_MPEG_REG(PARSER_SUB_END_PTR); parser_sub_rp = READ_MPEG_REG(PARSER_SUB_RP); buf->flag |= BUF_FLAG_PARSER; if (atomic_add_return(1, &esparser_use_count) == 1) { first_use = true; if (fetchbuf == 0) { printk("%s: no fetchbuf\n", __FUNCTION__); r = -ENOMEM; goto Err_1; } if (search_pattern == NULL) { search_pattern = (unsigned char *)kcalloc(1, SEARCH_PATTERN_LEN, GFP_KERNEL); if (search_pattern == NULL) { printk("%s: no search_pattern\n", __FUNCTION__); r = -ENOMEM; goto Err_1; } /* build a fake start code to get parser interrupt */ search_pattern[0] = 0x00; search_pattern[1] = 0x00; search_pattern[2] = 0x01; search_pattern[3] = 0xff; search_pattern_map = dma_map_single(NULL, search_pattern, SEARCH_PATTERN_LEN, DMA_TO_DEVICE); } /* reset PARSER with first esparser_init() call */ WRITE_MPEG_REG(RESET1_REGISTER, RESET_PARSER); /* TS data path */ #ifndef CONFIG_AM_DVB WRITE_MPEG_REG(FEC_INPUT_CONTROL, 0); #else tsdemux_set_reset_flag(); #endif CLEAR_MPEG_REG_MASK(TS_HIU_CTL, 1 << USE_HI_BSF_INTERFACE); CLEAR_MPEG_REG_MASK(TS_HIU_CTL_2, 1 << USE_HI_BSF_INTERFACE); CLEAR_MPEG_REG_MASK(TS_HIU_CTL_3, 1 << USE_HI_BSF_INTERFACE); CLEAR_MPEG_REG_MASK(TS_FILE_CONFIG, (1 << TS_HIU_ENABLE)); WRITE_MPEG_REG(PARSER_CONFIG, (10 << PS_CFG_PFIFO_EMPTY_CNT_BIT) | (1 << PS_CFG_MAX_ES_WR_CYCLE_BIT) | (16 << PS_CFG_MAX_FETCH_CYCLE_BIT)); WRITE_MPEG_REG(PFIFO_RD_PTR, 0); WRITE_MPEG_REG(PFIFO_WR_PTR, 0); WRITE_MPEG_REG(PARSER_SEARCH_PATTERN, ES_START_CODE_PATTERN); WRITE_MPEG_REG(PARSER_SEARCH_MASK, ES_START_CODE_MASK); WRITE_MPEG_REG(PARSER_CONFIG, (10 << PS_CFG_PFIFO_EMPTY_CNT_BIT) | (1 << PS_CFG_MAX_ES_WR_CYCLE_BIT) | PS_CFG_STARTCODE_WID_24 | PS_CFG_PFIFO_ACCESS_WID_8 | /* single byte pop */ (16 << PS_CFG_MAX_FETCH_CYCLE_BIT)); WRITE_MPEG_REG(PARSER_CONTROL, PARSER_AUTOSEARCH); tasklet_init(&esparser_tasklet, parser_tasklet, 0); } #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 /* hook stream buffer with PARSER */ if (HAS_HEVC_VDEC && (pts_type == PTS_TYPE_HEVC)) { CLEAR_VREG_MASK(HEVC_STREAM_CONTROL, 1); WRITE_MPEG_REG(PARSER_VIDEO_START_PTR, READ_VREG(HEVC_STREAM_START_ADDR)); WRITE_MPEG_REG(PARSER_VIDEO_END_PTR, READ_VREG(HEVC_STREAM_END_ADDR) - 8); CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_VID_MAN_RD_PTR); WRITE_VREG(DOS_GEN_CTRL0, 3<<1); // set vififo_vbuf_rp_sel=>hevc SET_VREG_MASK(HEVC_STREAM_CONTROL, (1<<3)|(0<<4)); // set use_parser_vbuf_wp SET_VREG_MASK(HEVC_STREAM_CONTROL, 1); // set stream_fetch_enable SET_VREG_MASK(HEVC_STREAM_FIFO_CTL, (1<<29)); // set stream_buffer_hole with 256 bytes video_data_parsed = 0; } else #endif if (pts_type == PTS_TYPE_VIDEO) { WRITE_MPEG_REG(PARSER_VIDEO_START_PTR, READ_VREG(VLD_MEM_VIFIFO_START_PTR)); WRITE_MPEG_REG(PARSER_VIDEO_END_PTR, READ_VREG(VLD_MEM_VIFIFO_END_PTR)); CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_VID_MAN_RD_PTR); WRITE_VREG(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); CLEAR_VREG_MASK(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); if (HAS_HEVC_VDEC) { WRITE_VREG(DOS_GEN_CTRL0, 0); // set vififo_vbuf_rp_sel=>vdec } video_data_parsed = 0; } else if (pts_type == PTS_TYPE_AUDIO) { WRITE_MPEG_REG(PARSER_AUDIO_START_PTR, READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); WRITE_MPEG_REG(PARSER_AUDIO_END_PTR, READ_MPEG_REG(AIU_MEM_AIFIFO_END_PTR)); CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_AUD_MAN_RD_PTR); WRITE_MPEG_REG(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); CLEAR_MPEG_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); audio_data_parsed = 0; } else if (buf->type & BUF_TYPE_SUBTITLE) { WRITE_MPEG_REG(PARSER_SUB_START_PTR, parser_sub_start_ptr); WRITE_MPEG_REG(PARSER_SUB_END_PTR, parser_sub_end_ptr); WRITE_MPEG_REG(PARSER_SUB_RP, parser_sub_rp); SET_MPEG_REG_MASK(PARSER_ES_CONTROL, (7 << ES_SUB_WR_ENDIAN_BIT) | ES_SUB_MAN_RD_PTR); } if (pts_type < PTS_TYPE_MAX) { r = pts_start(pts_type); if (r < 0) { printk("esparser_init: pts_start failed\n"); goto Err_1; } } #if 0 if (buf->flag & BUF_FLAG_FIRST_TSTAMP) { if (buf->type == BUF_TYPE_VIDEO) { es_vpts_checkin(buf, buf->first_tstamp); } else if (buf->type == BUF_TYPE_AUDIO) { es_apts_checkin(buf, buf->first_tstamp); } buf->flag &= ~BUF_FLAG_FIRST_TSTAMP; } #endif if (first_use) { r = request_irq(INT_PARSER, parser_isr, IRQF_SHARED, "esparser", (void *)esparser_id); if (r) { printk("esparser_init: irq register failed.\n"); goto Err_2; } WRITE_MPEG_REG(PARSER_INT_STATUS, 0xffff); WRITE_MPEG_REG(PARSER_INT_ENABLE, PARSER_INTSTAT_SC_FOUND << PARSER_INT_HOST_EN_BIT); } return 0; Err_2: pts_stop(pts_type); Err_1: atomic_dec(&esparser_use_count); buf->flag &= ~BUF_FLAG_PARSER; return r; }
s32 rmparser_init(void) { s32 r; parse_halt = 0; if (fetchbuf == 0) { printk("%s: no fetchbuf\n", __FUNCTION__); return -ENOMEM; } WRITE_MPEG_REG(RESET1_REGISTER, RESET_PARSER); /* TS data path */ /* Ignore FEC control for WetekPlay */ #ifndef CONFIG_WETEK #ifndef CONFIG_AM_DVB WRITE_MPEG_REG(FEC_INPUT_CONTROL, 0); #else tsdemux_set_reset_flag(); #endif #endif CLEAR_MPEG_REG_MASK(TS_HIU_CTL, 1 << USE_HI_BSF_INTERFACE); CLEAR_MPEG_REG_MASK(TS_HIU_CTL_2, 1 << USE_HI_BSF_INTERFACE); CLEAR_MPEG_REG_MASK(TS_HIU_CTL_3, 1 << USE_HI_BSF_INTERFACE); CLEAR_MPEG_REG_MASK(TS_FILE_CONFIG, (1 << TS_HIU_ENABLE)); /* hook stream buffer with PARSER */ WRITE_MPEG_REG(PARSER_VIDEO_START_PTR, READ_VREG(VLD_MEM_VIFIFO_START_PTR)); WRITE_MPEG_REG(PARSER_VIDEO_END_PTR, READ_VREG(VLD_MEM_VIFIFO_END_PTR)); CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_VID_MAN_RD_PTR); WRITE_MPEG_REG(PARSER_AUDIO_START_PTR, READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); WRITE_MPEG_REG(PARSER_AUDIO_END_PTR, READ_MPEG_REG(AIU_MEM_AIFIFO_END_PTR)); CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_AUD_MAN_RD_PTR); WRITE_VREG(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); CLEAR_VREG_MASK(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); WRITE_MPEG_REG(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); CLEAR_MPEG_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); WRITE_MPEG_REG(PFIFO_RD_PTR, 0); WRITE_MPEG_REG(PFIFO_WR_PTR, 0); WRITE_MPEG_REG(PARSER_SEARCH_MASK, 0); WRITE_MPEG_REG(PARSER_CONTROL, (ES_SEARCH | ES_PARSER_START)); #ifdef MANAGE_PTS if (pts_start(PTS_TYPE_VIDEO) < 0) { goto Err_1; } if (pts_start(PTS_TYPE_AUDIO) < 0) { goto Err_2; } #endif /* enable interrupt */ r = request_irq(INT_PARSER, rm_parser_isr, IRQF_SHARED, "rmparser", (void *)rmparser_id); if (r) { printk("RM parser irq register failed.\n"); goto Err_3; } WRITE_MPEG_REG(PARSER_INT_STATUS, 0xffff); WRITE_MPEG_REG(PARSER_INT_ENABLE, ((PARSER_INT_ALL & (~PARSER_INTSTAT_FETCH_CMD)) << PARSER_INT_AMRISC_EN_BIT) | (PARSER_INTSTAT_FETCH_CMD << PARSER_INT_HOST_EN_BIT)); return 0; Err_3: pts_stop(PTS_TYPE_AUDIO); Err_2: pts_stop(PTS_TYPE_VIDEO); Err_1: return -ENOENT; }
s32 tsdemux_init(u32 vid, u32 aid, u32 sid) { s32 r; u32 parser_sub_start_ptr; u32 parser_sub_end_ptr; u32 parser_sub_rp; parser_sub_start_ptr = READ_MPEG_REG(PARSER_SUB_START_PTR); parser_sub_end_ptr = READ_MPEG_REG(PARSER_SUB_END_PTR); parser_sub_rp = READ_MPEG_REG(PARSER_SUB_RP); WRITE_MPEG_REG(RESET1_REGISTER, RESET_PARSER); #ifdef ENABLE_DEMUX_DRIVER tsdemux_reset(); #else WRITE_MPEG_REG(RESET1_REGISTER, RESET_PARSER | RESET_DEMUXSTB); WRITE_MPEG_REG(STB_TOP_CONFIG, 0); WRITE_MPEG_REG(DEMUX_CONTROL, 0); #endif /* set PID filter */ printk("tsdemux video_pid = 0x%x, audio_pid = 0x%x, sub_pid = 0x%x\n", vid, aid, sid); #ifndef ENABLE_DEMUX_DRIVER WRITE_MPEG_REG(FM_WR_DATA, (((vid & 0x1fff) | (VIDEO_PACKET << 13)) << 16) | ((aid & 0x1fff) | (AUDIO_PACKET << 13))); WRITE_MPEG_REG(FM_WR_ADDR, 0x8000); while (READ_MPEG_REG(FM_WR_ADDR) & 0x8000) { ; } WRITE_MPEG_REG(FM_WR_DATA, (((sid & 0x1fff) | (SUB_PACKET << 13)) << 16) | 0xffff); WRITE_MPEG_REG(FM_WR_ADDR, 0x8001); while (READ_MPEG_REG(FM_WR_ADDR) & 0x8000) { ; } WRITE_MPEG_REG(MAX_FM_COMP_ADDR, 1); WRITE_MPEG_REG(STB_INT_MASK, 0); WRITE_MPEG_REG(STB_INT_STATUS, 0xffff); /* TS data path */ WRITE_MPEG_REG(FEC_INPUT_CONTROL, 0x7000); WRITE_MPEG_REG(DEMUX_MEM_REQ_EN, (1 << VIDEO_PACKET) | (1 << AUDIO_PACKET) | (1 << SUB_PACKET)); WRITE_MPEG_REG(DEMUX_ENDIAN, (7 << OTHER_ENDIAN) | (7 << BYPASS_ENDIAN) | (0 << SECTION_ENDIAN)); WRITE_MPEG_REG(TS_HIU_CTL, 1 << USE_HI_BSF_INTERFACE); WRITE_MPEG_REG(TS_FILE_CONFIG, (demux_skipbyte << 16) | (6 << DES_OUT_DLY) | (3 << TRANSPORT_SCRAMBLING_CONTROL_ODD) | (1 << TS_HIU_ENABLE) | (4 << FEC_FILE_CLK_DIV)); /* enable TS demux */ WRITE_MPEG_REG(DEMUX_CONTROL, (1 << STB_DEMUX_ENABLE) | (1 << KEEP_DUPLICATE_PACKAGE)); #endif if (fetchbuf == 0) { printk("%s: no fetchbuf\n", __FUNCTION__); return -ENOMEM; } /* hook stream buffer with PARSER */ WRITE_MPEG_REG(PARSER_VIDEO_START_PTR, READ_MPEG_REG(VLD_MEM_VIFIFO_START_PTR)); WRITE_MPEG_REG(PARSER_VIDEO_END_PTR, READ_MPEG_REG(VLD_MEM_VIFIFO_END_PTR)); CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_VID_MAN_RD_PTR); WRITE_MPEG_REG(PARSER_AUDIO_START_PTR, READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); WRITE_MPEG_REG(PARSER_AUDIO_END_PTR, READ_MPEG_REG(AIU_MEM_AIFIFO_END_PTR)); CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_AUD_MAN_RD_PTR); WRITE_MPEG_REG(PARSER_CONFIG, (10 << PS_CFG_PFIFO_EMPTY_CNT_BIT) | (1 << PS_CFG_MAX_ES_WR_CYCLE_BIT) | (16 << PS_CFG_MAX_FETCH_CYCLE_BIT)); WRITE_MPEG_REG(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); CLEAR_MPEG_REG_MASK(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); WRITE_MPEG_REG(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); CLEAR_MPEG_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); WRITE_MPEG_REG(PARSER_SUB_START_PTR, parser_sub_start_ptr); WRITE_MPEG_REG(PARSER_SUB_END_PTR, parser_sub_end_ptr); WRITE_MPEG_REG(PARSER_SUB_RP, parser_sub_rp); SET_MPEG_REG_MASK(PARSER_ES_CONTROL, (7 << ES_SUB_WR_ENDIAN_BIT) | ES_SUB_MAN_RD_PTR); if ((r = pts_start(PTS_TYPE_VIDEO)) < 0) { printk("Video pts start failed.(%d)\n", r); goto err1; } if ((r = pts_start(PTS_TYPE_AUDIO)) < 0) { printk("Audio pts start failed.(%d)\n", r); goto err2; } r = request_irq(INT_PARSER, parser_isr, IRQF_SHARED, "tsdemux-fetch", (void *)tsdemux_fetch_id); if (r) { goto err3; } WRITE_MPEG_REG(PARSER_INT_STATUS, 0xffff); WRITE_MPEG_REG(PARSER_INT_ENABLE, PARSER_INTSTAT_FETCH_CMD << PARSER_INT_HOST_EN_BIT); WRITE_MPEG_REG(PARSER_VIDEO_HOLE, 0x400); WRITE_MPEG_REG(PARSER_AUDIO_HOLE, 0x400); discontinued_counter = 0; #ifndef ENABLE_DEMUX_DRIVER r = request_irq(INT_DEMUX, tsdemux_isr, IRQF_SHARED, "tsdemux-irq", (void *)tsdemux_irq_id); WRITE_MPEG_REG(STB_INT_MASK, (1 << SUB_PES_READY) | (1 << NEW_PDTS_READY) | (1 << DIS_CONTINUITY_PACKET)); if (r) { goto err4; } #else tsdemux_config(); tsdemux_request_irq(tsdemux_isr, (void *)tsdemux_irq_id); if (vid < 0x1FFF) { tsdemux_set_vid(vid); } if (aid < 0x1FFF) { tsdemux_set_aid(aid); } if (sid < 0x1FFF) { tsdemux_set_sid(sid); } #endif return 0; #ifndef ENABLE_DEMUX_DRIVER err4: free_irq(INT_PARSER, (void *)tsdemux_fetch_id); #endif err3: pts_stop(PTS_TYPE_AUDIO); err2: pts_stop(PTS_TYPE_VIDEO); err1: printk("TS Demux init failed.\n"); return -ENOENT; }