コード例 #1
0
ファイル: esparser.c プロジェクト: nmadrane/linux-meson
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;
}
コード例 #2
0
ファイル: rmparser.c プロジェクト: rofehr/linux-wetek
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;
}