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; }