s32 amvdec2_loadmc(const u32 *p) { if (HAS_VDEC2) { ulong timeout; s32 ret = 0; #ifdef AMVDEC_USE_STATIC_MEMORY if (mc_addr == NULL) #endif { mc_addr = kmalloc(MC_SIZE, GFP_KERNEL); } if (!mc_addr) { return -ENOMEM; } memcpy(mc_addr, p, MC_SIZE); mc_addr_map = dma_map_single(NULL, mc_addr, MC_SIZE, DMA_TO_DEVICE); WRITE_VREG(VDEC2_MPSR, 0); WRITE_VREG(VDEC2_CPSR, 0); /* Read CBUS register for timing */ timeout = READ_VREG(VDEC2_MPSR); timeout = READ_VREG(VDEC2_MPSR); timeout = jiffies + HZ; WRITE_VREG(VDEC2_IMEM_DMA_ADR, mc_addr_map); WRITE_VREG(VDEC2_IMEM_DMA_COUNT, 0x1000); WRITE_VREG(VDEC2_IMEM_DMA_CTRL, (0x8000 | (7 << 16))); while (READ_VREG(VDEC2_IMEM_DMA_CTRL) & 0x8000) { if (time_before(jiffies, timeout)) { schedule(); } else { printk("vdec2 load mc error\n"); ret = -EBUSY; break; } } dma_unmap_single(NULL, mc_addr_map, MC_SIZE, DMA_TO_DEVICE); #ifndef AMVDEC_USE_STATIC_MEMORY kfree(mc_addr); mc_addr = NULL; #endif return ret; } else { return 0; } }
static inline u32 buf_wp(u32 type) { u32 wp = #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 (type == BUF_TYPE_HEVC) ? READ_VREG(HEVC_STREAM_WR_PTR) : #endif (type == BUF_TYPE_VIDEO) ? READ_VREG(VLD_MEM_VIFIFO_WP) : (type == BUF_TYPE_AUDIO) ? READ_MPEG_REG(AIU_MEM_AIFIFO_MAN_WP) : READ_MPEG_REG(PARSER_SUB_START_PTR); return wp; }
u32 stbuf_space(struct stream_buf_s *buf) { /* reserved space for safe write, the parser fifo size is 1024byts, so reserve it */ int size; #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 if (HAS_HEVC_VDEC && buf->type == BUF_TYPE_HEVC) size = buf->canusebuf_size - READ_VREG(HEVC_STREAM_LEVEL); else #endif size = (buf->canusebuf_size - _READ_ST_REG(LEVEL)) ; #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6TVD if ((buf->type == BUF_TYPE_VIDEO) && (vdec_on(VDEC_2))) { if ((_READ_VDEC2_ST_REG(START_PTR) == _READ_ST_REG(START_PTR)) && (_READ_VDEC2_ST_REG(END_PTR) == _READ_ST_REG(END_PTR)) && (_READ_VDEC2_ST_REG(CONTROL) & MEM_CTRL_FILL_EN)) { size = min(size, (int)(buf->canusebuf_size - _READ_VDEC2_ST_REG(LEVEL))); } } #endif if(buf->canusebuf_size>=buf->buf_size/2) size=size-6*1024;//old reversed value,tobe full, reversed only... if ((buf->type == BUF_TYPE_VIDEO) || (HAS_HEVC_VDEC && buf->type == BUF_TYPE_HEVC)) { size -= READ_MPEG_REG(PARSER_VIDEO_HOLE); } return size > 0 ? size : 0; }
s32 amhcodec_loadmc(const u32 *p) { #ifdef AMVDEC_USE_STATIC_MEMORY if (mc_addr == NULL) #endif { mc_addr = kmalloc(MC_SIZE, GFP_KERNEL); } if (!mc_addr) { return -ENOMEM; } memcpy(mc_addr, p, MC_SIZE); mc_addr_map = dma_map_single(NULL, mc_addr, MC_SIZE, DMA_TO_DEVICE); WRITE_VREG(HCODEC_IMEM_DMA_ADR, mc_addr_map); WRITE_VREG(HCODEC_IMEM_DMA_COUNT, 0x100); WRITE_VREG(HCODEC_IMEM_DMA_CTRL, (0x8000 | (7 << 16))); while (READ_VREG(HCODEC_IMEM_DMA_CTRL) & 0x8000) { udelay(1000); } dma_unmap_single(NULL, mc_addr_map, MC_SIZE, DMA_TO_DEVICE); #ifndef AMVDEC_USE_STATIC_MEMORY kfree(mc_addr); #endif return 0; }
static irqreturn_t jpegdec_isr(int irq, void *dev_id) { WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); if ((dec->state & JPEGDEC_STAT_INFO_READY) == 0) { dec->info.width = READ_VREG(JPEG_PIC_WIDTH); dec->info.height = READ_VREG(JPEG_PIC_HEIGHT); dec->info.comp_num = READ_VREG(JPEG_INFO) >> 1; pr_dbg("ucode report picture size %dx%d, comp_num %d\n", dec->info.width, dec->info.height, dec->info.comp_num); if ((dec->info.comp_num != 1) && (dec->info.comp_num != 3)) { dec->state |= JPEGDEC_STAT_INFO_READY | JPEGDEC_STAT_UNSUPPORT; } else { dec->state |= JPEGDEC_STAT_INFO_READY | JPEGDEC_STAT_WAIT_DECCONFIG; } } else {
u32 stbuf_rp(struct stream_buf_s *buf) { #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 if (HAS_HEVC_VDEC) return (buf->type == BUF_TYPE_HEVC) ? READ_VREG(HEVC_STREAM_RD_PTR) : _READ_ST_REG(RP); else #endif return _READ_ST_REG(RP); }
static void amhevc_pg_enable(bool enable) { #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 if (HAS_HEVC_VDEC) { ulong timeout; if(!vdec_on(VDEC_HEVC)) return; if (enable) { // WRITE_VREG(VDEC2_GCLK_EN, 0x3ff); } else { timeout = jiffies + HZ / 10; while (READ_VREG(HEVC_MDEC_PIC_DC_STATUS) != 0) { if (time_after(jiffies, timeout)) { WRITE_VREG_BITS(HEVC_MDEC_PIC_DC_CTRL, 1, 0, 1); WRITE_VREG_BITS(HEVC_MDEC_PIC_DC_CTRL, 0, 0, 1); READ_VREG(HEVC_MDEC_PIC_DC_STATUS); READ_VREG(HEVC_MDEC_PIC_DC_STATUS); READ_VREG(HEVC_MDEC_PIC_DC_STATUS); break; } } timeout = jiffies + HZ / 10; while (READ_VREG(HEVC_DBLK_STATUS) & 1) { if (time_after(jiffies, timeout)) { WRITE_VREG(HEVC_DBLK_CTRL, 3); WRITE_VREG(HEVC_DBLK_CTRL, 0); READ_VREG(HEVC_DBLK_STATUS); READ_VREG(HEVC_DBLK_STATUS); READ_VREG(HEVC_DBLK_STATUS); break; } } timeout = jiffies + HZ / 10; while (READ_VREG(HEVC_DCAC_DMA_CTRL) & 0x8000) { if (time_after(jiffies, timeout)) { break; } } } } #endif }
static void amvdec2_pg_enable(bool enable) { if (HAS_VDEC2) { ulong timeout; if(!vdec_on(VDEC_2)) return; if (enable) { // WRITE_VREG(VDEC2_GCLK_EN, 0x3ff); } else { timeout = jiffies + HZ / 10; while (READ_VREG(VDEC2_MDEC_PIC_DC_STATUS) != 0) { if (time_after(jiffies, timeout)) { WRITE_VREG_BITS(VDEC2_MDEC_PIC_DC_CTRL, 1, 0, 1); WRITE_VREG_BITS(VDEC2_MDEC_PIC_DC_CTRL, 0, 0, 1); READ_VREG(VDEC2_MDEC_PIC_DC_STATUS); READ_VREG(VDEC2_MDEC_PIC_DC_STATUS); READ_VREG(VDEC2_MDEC_PIC_DC_STATUS); break; } } timeout = jiffies + HZ / 10; while (READ_VREG(VDEC2_DBLK_STATUS) & 1) { if (time_after(jiffies, timeout)) { WRITE_VREG(VDEC2_DBLK_CTRL, 3); WRITE_VREG(VDEC2_DBLK_CTRL, 0); READ_VREG(VDEC2_DBLK_STATUS); READ_VREG(VDEC2_DBLK_STATUS); READ_VREG(VDEC2_DBLK_STATUS); break; } } timeout = jiffies + HZ / 10; while (READ_VREG(VDEC2_DCAC_DMA_CTRL) & 0x8000) { if (time_after(jiffies, timeout)) { break; } } } } }
static void amhevc_pg_enable(bool enable) { if (has_hevc_vdec()) { ulong timeout; if (!vdec_on(VDEC_HEVC)) return; if (enable) { /* WRITE_VREG(VDEC2_GCLK_EN, 0x3ff); */ } else { timeout = jiffies + HZ / 10; while (READ_VREG(HEVC_MDEC_PIC_DC_STATUS) != 0) { if (time_after(jiffies, timeout)) { WRITE_VREG_BITS(HEVC_MDEC_PIC_DC_CTRL, 1, 0, 1); WRITE_VREG_BITS(HEVC_MDEC_PIC_DC_CTRL, 0, 0, 1); READ_VREG(HEVC_MDEC_PIC_DC_STATUS); READ_VREG(HEVC_MDEC_PIC_DC_STATUS); READ_VREG(HEVC_MDEC_PIC_DC_STATUS); break; } } timeout = jiffies + HZ / 10; while (READ_VREG(HEVC_DBLK_STATUS) & 1) { if (time_after(jiffies, timeout)) { WRITE_VREG(HEVC_DBLK_CTRL, 3); WRITE_VREG(HEVC_DBLK_CTRL, 0); READ_VREG(HEVC_DBLK_STATUS); READ_VREG(HEVC_DBLK_STATUS); READ_VREG(HEVC_DBLK_STATUS); break; } } timeout = jiffies + HZ / 10; while (READ_VREG(HEVC_DCAC_DMA_CTRL) & 0x8000) { if (time_after(jiffies, timeout)) break; } } } }
static int vdec_is_paused(void) { static unsigned long old_wp = -1, old_rp = -1, old_level = -1; unsigned long wp, rp, level; static int paused_time = 0; #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 if (HAS_HEVC_VDEC) { if ((vdec_on(VDEC_HEVC)) && (READ_VREG(HEVC_STREAM_CONTROL) & 1)) { wp = READ_VREG(HEVC_STREAM_WR_PTR); rp = READ_VREG(HEVC_STREAM_RD_PTR); level = READ_VREG(HEVC_STREAM_LEVEL); } else { wp = READ_VREG(VLD_MEM_VIFIFO_WP); rp = READ_VREG(VLD_MEM_VIFIFO_RP); level = READ_VREG(VLD_MEM_VIFIFO_LEVEL); } } else #endif { wp = READ_VREG(VLD_MEM_VIFIFO_WP); rp = READ_VREG(VLD_MEM_VIFIFO_RP); level = READ_VREG(VLD_MEM_VIFIFO_LEVEL); } if ((rp == old_rp && level > 1024) || /*have data,but output buffer is full */ (rp == old_rp && wp == old_wp && level == level)) { /*no write && not read*/ paused_time++; } else { paused_time = 0; } old_wp = wp; old_rp = rp; old_level = level; if (paused_time > 10) { return 1; } return 0; }
void amvdec_start(void) { #ifdef CONFIG_WAKELOCK amvdec_wake_lock(); #endif #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 READ_VREG(DOS_SW_RESET0); READ_VREG(DOS_SW_RESET0); READ_VREG(DOS_SW_RESET0); WRITE_VREG(DOS_SW_RESET0, (1<<12)|(1<<11)); WRITE_VREG(DOS_SW_RESET0, 0); READ_VREG(DOS_SW_RESET0); READ_VREG(DOS_SW_RESET0); READ_VREG(DOS_SW_RESET0); #else /* additional cbus dummy register reading for timing control */ READ_MPEG_REG(RESET0_REGISTER); READ_MPEG_REG(RESET0_REGISTER); READ_MPEG_REG(RESET0_REGISTER); READ_MPEG_REG(RESET0_REGISTER); WRITE_MPEG_REG(RESET0_REGISTER, RESET_VCPU | RESET_CCPU); READ_MPEG_REG(RESET0_REGISTER); READ_MPEG_REG(RESET0_REGISTER); READ_MPEG_REG(RESET0_REGISTER); #endif WRITE_VREG(MPSR, 0x0001); }
void amhevc_stop(void) { if (has_hevc_vdec()) { ulong timeout = jiffies + HZ; WRITE_VREG(HEVC_MPSR, 0); WRITE_VREG(HEVC_CPSR, 0); while (READ_VREG(HEVC_IMEM_DMA_CTRL) & 0x8000) { if (time_after(jiffies, timeout)) break; } READ_VREG(DOS_SW_RESET3); READ_VREG(DOS_SW_RESET3); READ_VREG(DOS_SW_RESET3); #ifdef CONFIG_WAKELOCK amvdec_wake_unlock(); #endif } }
void amvdec2_stop(void) { if (HAS_VDEC2) { ulong timeout = jiffies + HZ; WRITE_VREG(VDEC2_MPSR, 0); WRITE_VREG(VDEC2_CPSR, 0); while (READ_VREG(VDEC2_IMEM_DMA_CTRL) & 0x8000) { if (time_after(jiffies, timeout)) { break; } } READ_VREG(DOS_SW_RESET2); READ_VREG(DOS_SW_RESET2); READ_VREG(DOS_SW_RESET2); #ifdef CONFIG_WAKELOCK amvdec_wake_unlock(); #endif } }
static int vdec_is_paused(void) { static unsigned long old_wp = -1, old_rp = -1, old_level = -1; unsigned long wp, rp, level; static int paused_time = 0; wp = READ_VREG(VLD_MEM_VIFIFO_WP); rp = READ_VREG(VLD_MEM_VIFIFO_RP); level = READ_VREG(VLD_MEM_VIFIFO_LEVEL); if ((rp == old_rp && level > 1024) || /*have data,but output buffer is fulle*/ (rp == old_rp && wp == old_wp && level == level)) { /*no write && not read*/ paused_time++; } else { paused_time = 0; } old_wp = wp; old_rp = rp; old_level = level; if (paused_time > 10) { return 1; } return 0; }
void amvdec_stop(void) { ulong timeout = jiffies + HZ; WRITE_VREG(MPSR, 0); WRITE_VREG(CPSR, 0); while (READ_VREG(IMEM_DMA_CTRL) & 0x8000) { if (time_after(jiffies, timeout)) { break; } } #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 READ_VREG(DOS_SW_RESET0); READ_VREG(DOS_SW_RESET0); READ_VREG(DOS_SW_RESET0); WRITE_VREG(DOS_SW_RESET0, (1<<12)|(1<<11)); WRITE_VREG(DOS_SW_RESET0, 0); READ_VREG(DOS_SW_RESET0); READ_VREG(DOS_SW_RESET0); READ_VREG(DOS_SW_RESET0); #else WRITE_MPEG_REG(RESET0_REGISTER, RESET_VCPU | RESET_CCPU); /* additional cbus dummy register reading for timing control */ READ_MPEG_REG(RESET0_REGISTER); READ_MPEG_REG(RESET0_REGISTER); READ_MPEG_REG(RESET0_REGISTER); READ_MPEG_REG(RESET0_REGISTER); #endif #ifdef CONFIG_WAKELOCK amvdec_wake_unlock(); #endif }
void amvdec2_start(void) { if (HAS_VDEC2) { #ifdef CONFIG_WAKELOCK amvdec_wake_lock(); #endif READ_VREG(DOS_SW_RESET2); READ_VREG(DOS_SW_RESET2); READ_VREG(DOS_SW_RESET2); WRITE_VREG(DOS_SW_RESET2, (1<<12)|(1<<11)); WRITE_VREG(DOS_SW_RESET2, 0); READ_VREG(DOS_SW_RESET2); READ_VREG(DOS_SW_RESET2); READ_VREG(DOS_SW_RESET2); WRITE_VREG(VDEC2_MPSR, 0x0001); } }
void amhevc_start(void) { if (HAS_HEVC_VDEC) { #ifdef CONFIG_WAKELOCK amvdec_wake_lock(); #endif READ_VREG(DOS_SW_RESET3); READ_VREG(DOS_SW_RESET3); READ_VREG(DOS_SW_RESET3); WRITE_VREG(DOS_SW_RESET3, (1<<12)|(1<<11)); WRITE_VREG(DOS_SW_RESET3, 0); READ_VREG(DOS_SW_RESET3); READ_VREG(DOS_SW_RESET3); READ_VREG(DOS_SW_RESET3); WRITE_VREG(HEVC_MPSR, 0x0001); } }
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; }
static void amvdec_pg_enable(bool enable) { ulong timeout; if (enable) { AMVDEC_CLK_GATE_ON(MDEC_CLK_PIC_DC); AMVDEC_CLK_GATE_ON(MDEC_CLK_DBLK); AMVDEC_CLK_GATE_ON(MC_CLK); AMVDEC_CLK_GATE_ON(IQIDCT_CLK); /* AMVDEC_CLK_GATE_ON(VLD_CLK); */ AMVDEC_CLK_GATE_ON(AMRISC); /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6TVD */ if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) WRITE_VREG(GCLK_EN, 0x3ff); /* #endif */ CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31); } else { AMVDEC_CLK_GATE_OFF(AMRISC); timeout = jiffies + HZ / 10; while (READ_VREG(MDEC_PIC_DC_STATUS) != 0) { if (time_after(jiffies, timeout)) { WRITE_VREG_BITS(MDEC_PIC_DC_CTRL, 1, 0, 1); WRITE_VREG_BITS(MDEC_PIC_DC_CTRL, 0, 0, 1); READ_VREG(MDEC_PIC_DC_STATUS); READ_VREG(MDEC_PIC_DC_STATUS); READ_VREG(MDEC_PIC_DC_STATUS); break; } } AMVDEC_CLK_GATE_OFF(MDEC_CLK_PIC_DC); timeout = jiffies + HZ / 10; while (READ_VREG(DBLK_STATUS) & 1) { if (time_after(jiffies, timeout)) { WRITE_VREG(DBLK_CTRL, 3); WRITE_VREG(DBLK_CTRL, 0); READ_VREG(DBLK_STATUS); READ_VREG(DBLK_STATUS); READ_VREG(DBLK_STATUS); break; } } AMVDEC_CLK_GATE_OFF(MDEC_CLK_DBLK); timeout = jiffies + HZ / 10; while (READ_VREG(MC_STATUS0) & 1) { if (time_after(jiffies, timeout)) { SET_VREG_MASK(MC_CTRL1, 0x9); CLEAR_VREG_MASK(MC_CTRL1, 0x9); READ_VREG(MC_STATUS0); READ_VREG(MC_STATUS0); READ_VREG(MC_STATUS0); break; } } AMVDEC_CLK_GATE_OFF(MC_CLK); timeout = jiffies + HZ / 10; while (READ_VREG(DCAC_DMA_CTRL) & 0x8000) { if (time_after(jiffies, timeout)) break; } AMVDEC_CLK_GATE_OFF(IQIDCT_CLK); /* AMVDEC_CLK_GATE_OFF(VLD_CLK); */ } }
static void amvdec_pg_enable(bool enable) { ulong timeout; if (enable) { AMVDEC_CLK_GATE_ON(MDEC_CLK_PIC_DC); AMVDEC_CLK_GATE_ON(MDEC_CLK_DBLK); AMVDEC_CLK_GATE_ON(MC_CLK); AMVDEC_CLK_GATE_ON(IQIDCT_CLK); //AMVDEC_CLK_GATE_ON(VLD_CLK); AMVDEC_CLK_GATE_ON(AMRISC); } else { AMVDEC_CLK_GATE_OFF(AMRISC); timeout = jiffies + HZ / 10; while (READ_VREG(MDEC_PIC_DC_STATUS) != 0) { if (time_after(jiffies, timeout)) { WRITE_VREG_BITS(MDEC_PIC_DC_CTRL, 1, 0, 1); WRITE_VREG_BITS(MDEC_PIC_DC_CTRL, 0, 0, 1); READ_VREG(MDEC_PIC_DC_STATUS); READ_VREG(MDEC_PIC_DC_STATUS); READ_VREG(MDEC_PIC_DC_STATUS); break; } } AMVDEC_CLK_GATE_OFF(MDEC_CLK_PIC_DC); timeout = jiffies + HZ / 10; while (READ_VREG(DBLK_STATUS) & 1) { if (time_after(jiffies, timeout)) { WRITE_VREG(DBLK_CTRL, 3); WRITE_VREG(DBLK_CTRL, 0); READ_VREG(DBLK_STATUS); READ_VREG(DBLK_STATUS); READ_VREG(DBLK_STATUS); break; } } AMVDEC_CLK_GATE_OFF(MDEC_CLK_DBLK); timeout = jiffies + HZ / 10; while (READ_VREG(MC_STATUS0) & 1) { if (time_after(jiffies, timeout)) { SET_VREG_MASK(MC_CTRL1, 0x9); CLEAR_VREG_MASK(MC_CTRL1, 0x9); READ_VREG(MC_STATUS0); READ_VREG(MC_STATUS0); READ_VREG(MC_STATUS0); break; } } AMVDEC_CLK_GATE_OFF(MC_CLK); timeout = jiffies + HZ / 10; while (READ_VREG(DCAC_DMA_CTRL) & 0x8000) { if (time_after(jiffies, timeout)) { break; } } AMVDEC_CLK_GATE_OFF(IQIDCT_CLK); //AMVDEC_CLK_GATE_OFF(VLD_CLK); } }
static irqreturn_t vmjpeg_isr(int irq, void *dev_id) { u32 reg, offset, pts, pts_valid = 0; vframe_t *vf = NULL; WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); reg = READ_VREG(MREG_FROM_AMRISC); if (reg & PICINFO_BUF_IDX_MASK) { offset = READ_VREG(MREG_FRAME_OFFSET); if (pts_lookup_offset(PTS_TYPE_VIDEO, offset, &pts, 0) == 0) { pts_valid = 1; } if ((reg & PICINFO_INTERLACE) == 0) { u32 index = ((reg & PICINFO_BUF_IDX_MASK) - 1) & 3; if (index >= DECODE_BUFFER_NUM_MAX) { printk("fatal error, invalid buffer index."); return IRQ_HANDLED; } if (kfifo_get(&newframe_q, &vf) == 0) { printk("fatal error, no available buffer slot."); return IRQ_HANDLED; } set_frame_info(vf); vf->index = index; #ifdef NV21 vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD | VIDTYPE_VIU_NV21; #else vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; #endif vf->canvas0Addr = vf->canvas1Addr = index2canvas0(index); vf->pts = (pts_valid) ? pts : 0; vf->orientation = 0 ; vfbuf_use[index]++; kfifo_put(&display_q, (const vframe_t **)&vf); vf_notify_receiver(PROVIDER_NAME,VFRAME_EVENT_PROVIDER_VFRAME_READY,NULL); } else { u32 index = ((reg & PICINFO_BUF_IDX_MASK) - 1) & 3; if (index >= DECODE_BUFFER_NUM_MAX) { printk("fatal error, invalid buffer index."); return IRQ_HANDLED; } if (kfifo_get(&newframe_q, &vf) == 0) { printk("fatal error, no available buffer slot."); return IRQ_HANDLED; } set_frame_info(vf); vf->index = index; #if 0 if (reg & PICINFO_AVI1) { /* AVI1 format */ if (reg & PICINFO_INTERLACE_AVI1_BOT) { vf->type = VIDTYPE_INTERLACE_BOTTOM | VIDTYPE_INTERLACE_FIRST; } else { vf->type = VIDTYPE_INTERLACE_TOP; } } else { if (reg & PICINFO_INTERLACE_FIRST) { vf->type = VIDTYPE_INTERLACE_TOP | VIDTYPE_INTERLACE_FIRST; } else { vf->type = VIDTYPE_INTERLACE_BOTTOM; } } vf->type |= VIDTYPE_VIU_FIELD; #ifdef NV21 vf->type |= VIDTYPE_VIU_NV21; #endif vf->duration >>= 1; vf->canvas0Addr = vf->canvas1Addr = index2canvas0(index); vf->orientation = 0 ; if ((vf->type & VIDTYPE_INTERLACE_FIRST) && (pts_valid)) { vf->pts = pts; } else { vf->pts = 0; } vfbuf_use[index]++; kfifo_put(&display_q, (const vframe_t **)&vf); #else /* send whole frame by weaving top & bottom field */ #ifdef NV21 vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_NV21; #else vf->type = VIDTYPE_PROGRESSIVE; #endif vf->canvas0Addr = index2canvas0(index); vf->canvas1Addr = index2canvas1(index); vf->orientation = 0 ; if (pts_valid) { vf->pts = pts; } else { vf->pts = 0; } vfbuf_use[index]++; kfifo_put(&display_q, (const vframe_t **)&vf); vf_notify_receiver(PROVIDER_NAME,VFRAME_EVENT_PROVIDER_VFRAME_READY,NULL); #endif } WRITE_VREG(MREG_FROM_AMRISC, 0); }
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; }
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; }
static void amvdec_pg_enable(bool enable) { ulong timeout; if (enable) { CLK_GATE_ON(MDEC_CLK_PIC_DC); CLK_GATE_ON(MDEC_CLK_DBLK); CLK_GATE_ON(MC_CLK); CLK_GATE_ON(IQIDCT_CLK); //CLK_GATE_ON(VLD_CLK); CLK_GATE_ON(AMRISC); } else { CLK_GATE_OFF(AMRISC); timeout = jiffies + HZ / 10; while (READ_VREG(MDEC_PIC_DC_STATUS) != 0) { if (time_after(jiffies, timeout)) { WRITE_VREG_BITS(MDEC_PIC_DC_CTRL, 1, 0, 1); WRITE_VREG_BITS(MDEC_PIC_DC_CTRL, 0, 0, 1); READ_VREG(MDEC_PIC_DC_STATUS); READ_VREG(MDEC_PIC_DC_STATUS); READ_VREG(MDEC_PIC_DC_STATUS); break; } } CLK_GATE_OFF(MDEC_CLK_PIC_DC); timeout = jiffies + HZ / 10; while (READ_VREG(DBLK_STATUS) & 1) { if (time_after(jiffies, timeout)) { WRITE_VREG(DBLK_CTRL, 3); WRITE_VREG(DBLK_CTRL, 0); READ_VREG(DBLK_STATUS); READ_VREG(DBLK_STATUS); READ_VREG(DBLK_STATUS); break; } } CLK_GATE_OFF(MDEC_CLK_DBLK); timeout = jiffies + HZ / 10; while (READ_VREG(MC_STATUS0) & 1) { if (time_after(jiffies, timeout)) { SET_VREG_MASK(MC_CTRL1, 0x9); CLEAR_VREG_MASK(MC_CTRL1, 0x9); READ_VREG(MC_STATUS0); READ_VREG(MC_STATUS0); READ_VREG(MC_STATUS0); break; } } CLK_GATE_OFF(MC_CLK); timeout = jiffies + HZ / 10; while (READ_VREG(DCAC_DMA_CTRL) & 0x8000) { if (time_after(jiffies, timeout)) { break; } } #ifdef CONFIG_ARCH_MESON6 WRITE_VREG(DOS_SW_RESET0, (1 << 4)); WRITE_VREG(DOS_SW_RESET0, 0); READ_VREG(DOS_SW_RESET0); READ_VREG(DOS_SW_RESET0); READ_VREG(DOS_SW_RESET0); #else WRITE_MPEG_REG(RESET0_REGISTER, RESET_VLD_PART); READ_MPEG_REG(RESET0_REGISTER); READ_MPEG_REG(RESET0_REGISTER); READ_MPEG_REG(RESET0_REGISTER); #endif CLK_GATE_OFF(IQIDCT_CLK); //CLK_GATE_OFF(VLD_CLK); } }
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; }
static inline u32 buf_wp(u32 type) { return (type == BUF_TYPE_VIDEO) ? READ_VREG(VLD_MEM_VIFIFO_WP) : (type == BUF_TYPE_AUDIO) ? READ_MPEG_REG(AIU_MEM_AIFIFO_MAN_WP) : READ_MPEG_REG(PARSER_SUB_START_PTR); }
static s32 amvdec_loadmc(const u32 *p) { ulong timeout; s32 ret = 0; #ifdef AMVDEC_USE_STATIC_MEMORY if (mc_addr == NULL) { #else { #endif mc_addr = kmalloc(MC_SIZE, GFP_KERNEL); } if (!mc_addr) return -ENOMEM; memcpy(mc_addr, p, MC_SIZE); mc_addr_map = dma_map_single(amports_get_dma_device(), mc_addr, MC_SIZE, DMA_TO_DEVICE); WRITE_VREG(MPSR, 0); WRITE_VREG(CPSR, 0); /* Read CBUS register for timing */ timeout = READ_VREG(MPSR); timeout = READ_VREG(MPSR); timeout = jiffies + HZ; WRITE_VREG(IMEM_DMA_ADR, mc_addr_map); WRITE_VREG(IMEM_DMA_COUNT, 0x1000); WRITE_VREG(IMEM_DMA_CTRL, (0x8000 | (7 << 16))); while (READ_VREG(IMEM_DMA_CTRL) & 0x8000) { if (time_before(jiffies, timeout)) schedule(); else { pr_err("vdec load mc error\n"); ret = -EBUSY; break; } } dma_unmap_single(amports_get_dma_device(), mc_addr_map, MC_SIZE, DMA_TO_DEVICE); #ifndef AMVDEC_USE_STATIC_MEMORY kfree(mc_addr); mc_addr = NULL; #endif return ret; } s32 amvdec_loadmc_ex(enum vformat_e type, const char *name, char *def) { return am_loadmc_ex(type, name, def, &amvdec_loadmc); } static s32 amvdec2_loadmc(const u32 *p) { if (has_vdec2()) { ulong timeout; s32 ret = 0; #ifdef AMVDEC_USE_STATIC_MEMORY if (mc_addr == NULL) { #else { #endif mc_addr = kmalloc(MC_SIZE, GFP_KERNEL); } if (!mc_addr) return -ENOMEM; memcpy(mc_addr, p, MC_SIZE); mc_addr_map = dma_map_single(amports_get_dma_device(), mc_addr, MC_SIZE, DMA_TO_DEVICE); WRITE_VREG(VDEC2_MPSR, 0); WRITE_VREG(VDEC2_CPSR, 0); /* Read CBUS register for timing */ timeout = READ_VREG(VDEC2_MPSR); timeout = READ_VREG(VDEC2_MPSR); timeout = jiffies + HZ; WRITE_VREG(VDEC2_IMEM_DMA_ADR, mc_addr_map); WRITE_VREG(VDEC2_IMEM_DMA_COUNT, 0x1000); WRITE_VREG(VDEC2_IMEM_DMA_CTRL, (0x8000 | (7 << 16))); while (READ_VREG(VDEC2_IMEM_DMA_CTRL) & 0x8000) { if (time_before(jiffies, timeout)) schedule(); else { pr_err("vdec2 load mc error\n"); ret = -EBUSY; break; } } dma_unmap_single(amports_get_dma_device(), mc_addr_map, MC_SIZE, DMA_TO_DEVICE); #ifndef AMVDEC_USE_STATIC_MEMORY kfree(mc_addr); mc_addr = NULL; #endif return ret; } else return 0; } s32 amvdec2_loadmc_ex(enum vformat_e type, const char *name, char *def) { if (has_vdec2()) return am_loadmc_ex(type, name, def, &amvdec2_loadmc); else return 0; } s32 amhcodec_loadmc(const u32 *p) { #ifdef AMVDEC_USE_STATIC_MEMORY if (mc_addr == NULL) { #else { #endif mc_addr = kmalloc(MC_SIZE, GFP_KERNEL); } if (!mc_addr) return -ENOMEM; memcpy(mc_addr, p, MC_SIZE); mc_addr_map = dma_map_single(amports_get_dma_device(), mc_addr, MC_SIZE, DMA_TO_DEVICE); WRITE_VREG(HCODEC_IMEM_DMA_ADR, mc_addr_map); WRITE_VREG(HCODEC_IMEM_DMA_COUNT, 0x100); WRITE_VREG(HCODEC_IMEM_DMA_CTRL, (0x8000 | (7 << 16))); while (READ_VREG(HCODEC_IMEM_DMA_CTRL) & 0x8000) udelay(1000); dma_unmap_single(amports_get_dma_device(), mc_addr_map, MC_SIZE, DMA_TO_DEVICE); #ifndef AMVDEC_USE_STATIC_MEMORY kfree(mc_addr); #endif return 0; } s32 amhcodec_loadmc_ex(enum vformat_e type, const char *name, char *def) { return am_loadmc_ex(type, name, def, &amhcodec_loadmc); } static s32 amhevc_loadmc(const u32 *p) { ulong timeout; s32 ret = 0; if (has_hevc_vdec()) { #ifdef AMVDEC_USE_STATIC_MEMORY if (mc_addr == NULL) { #else { #endif mc_addr = kmalloc(MC_SIZE, GFP_KERNEL); } if (!mc_addr) return -ENOMEM; memcpy(mc_addr, p, MC_SIZE); mc_addr_map = dma_map_single(amports_get_dma_device(), mc_addr, MC_SIZE, DMA_TO_DEVICE); WRITE_VREG(HEVC_MPSR, 0); WRITE_VREG(HEVC_CPSR, 0); /* Read CBUS register for timing */ timeout = READ_VREG(HEVC_MPSR); timeout = READ_VREG(HEVC_MPSR); timeout = jiffies + HZ; WRITE_VREG(HEVC_IMEM_DMA_ADR, mc_addr_map); WRITE_VREG(HEVC_IMEM_DMA_COUNT, 0x1000); WRITE_VREG(HEVC_IMEM_DMA_CTRL, (0x8000 | (7 << 16))); while (READ_VREG(HEVC_IMEM_DMA_CTRL) & 0x8000) { if (time_before(jiffies, timeout)) schedule(); else { pr_err("vdec2 load mc error\n"); ret = -EBUSY; break; } } dma_unmap_single(amports_get_dma_device(), mc_addr_map, MC_SIZE, DMA_TO_DEVICE); #ifndef AMVDEC_USE_STATIC_MEMORY kfree(mc_addr); mc_addr = NULL; #endif } return ret; } s32 amhevc_loadmc_ex(enum vformat_e type, const char *name, char *def) { if (has_hevc_vdec()) return am_loadmc_ex(type, name, def, &amhevc_loadmc); else return 0; } void amvdec_start(void) { #ifdef CONFIG_WAKELOCK amvdec_wake_lock(); #endif /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M6) { READ_VREG(DOS_SW_RESET0); READ_VREG(DOS_SW_RESET0); READ_VREG(DOS_SW_RESET0); WRITE_VREG(DOS_SW_RESET0, (1 << 12) | (1 << 11)); WRITE_VREG(DOS_SW_RESET0, 0); READ_VREG(DOS_SW_RESET0); READ_VREG(DOS_SW_RESET0); READ_VREG(DOS_SW_RESET0); } else { /* #else */ /* additional cbus dummy register reading for timing control */ READ_MPEG_REG(RESET0_REGISTER); READ_MPEG_REG(RESET0_REGISTER); READ_MPEG_REG(RESET0_REGISTER); READ_MPEG_REG(RESET0_REGISTER); WRITE_MPEG_REG(RESET0_REGISTER, RESET_VCPU | RESET_CCPU); READ_MPEG_REG(RESET0_REGISTER); READ_MPEG_REG(RESET0_REGISTER); READ_MPEG_REG(RESET0_REGISTER); } /* #endif */ WRITE_VREG(MPSR, 0x0001); } void amvdec2_start(void) { if (has_vdec2()) { #ifdef CONFIG_WAKELOCK amvdec_wake_lock(); #endif READ_VREG(DOS_SW_RESET2); READ_VREG(DOS_SW_RESET2); READ_VREG(DOS_SW_RESET2); WRITE_VREG(DOS_SW_RESET2, (1 << 12) | (1 << 11)); WRITE_VREG(DOS_SW_RESET2, 0); READ_VREG(DOS_SW_RESET2); READ_VREG(DOS_SW_RESET2); READ_VREG(DOS_SW_RESET2); WRITE_VREG(VDEC2_MPSR, 0x0001); } } void amhcodec_start(void) { WRITE_VREG(HCODEC_MPSR, 0x0001); } void amhevc_start(void) { if (has_hevc_vdec()) { #ifdef CONFIG_WAKELOCK amvdec_wake_lock(); #endif READ_VREG(DOS_SW_RESET3); READ_VREG(DOS_SW_RESET3); READ_VREG(DOS_SW_RESET3); WRITE_VREG(DOS_SW_RESET3, (1 << 12) | (1 << 11)); WRITE_VREG(DOS_SW_RESET3, 0); READ_VREG(DOS_SW_RESET3); READ_VREG(DOS_SW_RESET3); READ_VREG(DOS_SW_RESET3); WRITE_VREG(HEVC_MPSR, 0x0001); } } void amvdec_stop(void) { ulong timeout = jiffies + HZ; WRITE_VREG(MPSR, 0); WRITE_VREG(CPSR, 0); while (READ_VREG(IMEM_DMA_CTRL) & 0x8000) { if (time_after(jiffies, timeout)) break; } /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M6) { READ_VREG(DOS_SW_RESET0); READ_VREG(DOS_SW_RESET0); READ_VREG(DOS_SW_RESET0); WRITE_VREG(DOS_SW_RESET0, (1 << 12) | (1 << 11)); WRITE_VREG(DOS_SW_RESET0, 0); READ_VREG(DOS_SW_RESET0); READ_VREG(DOS_SW_RESET0); READ_VREG(DOS_SW_RESET0); } else { /* #else */ WRITE_MPEG_REG(RESET0_REGISTER, RESET_VCPU | RESET_CCPU); /* additional cbus dummy register reading for timing control */ READ_MPEG_REG(RESET0_REGISTER); READ_MPEG_REG(RESET0_REGISTER); READ_MPEG_REG(RESET0_REGISTER); READ_MPEG_REG(RESET0_REGISTER); } /* #endif */ #ifdef CONFIG_WAKELOCK amvdec_wake_unlock(); #endif }