116 files changed, 25845 insertions, 36303 deletions
diff --git a/drivers/frame_provider/decoder/avs_multi/avs_multi.c b/drivers/frame_provider/decoder/avs_multi/avs_multi.c index 11813ad..f041bf7 100644 --- a/drivers/frame_provider/decoder/avs_multi/avs_multi.c +++ b/drivers/frame_provider/decoder/avs_multi/avs_multi.c @@ -14,7 +14,6 @@ * more details. * */ -#define DEBUG #include <linux/kernel.h> #include <linux/types.h> #include <linux/errno.h> @@ -47,9 +46,22 @@ #include <linux/amlogic/tee.h> #define DEBUG_MULTI_FLAG 0 +/* +#define DEBUG_WITH_SINGLE_MODE +#define DEBUG_MULTI_WITH_AUTOMODE +#define DEBUG_MULTI_FRAME_INS +*/ + + +#define USE_DYNAMIC_BUF_NUM +#ifdef DEBUG_WITH_SINGLE_MODE #define DRIVER_NAME "amvdec_avs" #define MODULE_NAME "amvdec_avs" +#else +#define DRIVER_NAME "ammvdec_avs" +#define MODULE_NAME "ammvdec_avs" +#endif #define MULTI_DRIVER_NAME "ammvdec_avs" @@ -92,23 +104,28 @@ #define AVS_OFFSET_REG AV_SCRATCH_C #define MEM_OFFSET_REG AV_SCRATCH_F #define AVS_ERROR_RECOVERY_MODE AV_SCRATCH_G +#define DECODE_PIC_COUNT AV_SCRATCH_G #define DECODE_MODE AV_SCRATCH_6 #define DECODE_MODE_SINGLE 0x0 #define DECODE_MODE_MULTI_FRAMEBASE 0x1 #define DECODE_MODE_MULTI_STREAMBASE 0x2 +#define DECODE_MODE_MULTI_STREAMBASE_CONT 0x3 #define DECODE_STATUS AV_SCRATCH_H #define DECODE_STATUS_PIC_DONE 0x1 #define DECODE_STATUS_DECODE_BUF_EMPTY 0x2 #define DECODE_STATUS_SEARCH_BUF_EMPTY 0x3 +#define DECODE_STATUS_SKIP_PIC_DONE 0x4 #define DECODE_SEARCH_HEAD 0xff #define DECODE_STOP_POS AV_SCRATCH_J #define DECODE_LMEM_BUF_ADR AV_SCRATCH_I -#define VF_POOL_SIZE 32 +#define DECODE_CFG AV_SCRATCH_K + +#define VF_POOL_SIZE 64 #define PUT_INTERVAL (HZ/100) #if 1 /*MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8*/ @@ -118,6 +135,18 @@ #define INT_AMVENCODER INT_MAILBOX_1A #endif +#ifdef USE_DYNAMIC_BUF_NUM +static unsigned int buf_spec_reg[] = { + AV_SCRATCH_0, + AV_SCRATCH_1, + AV_SCRATCH_2, + AV_SCRATCH_3, + AV_SCRATCH_7, /*AVS_SOS_COUNT*/ + AV_SCRATCH_D, /*DEBUG_REG2*/ + AV_SCRATCH_E, /*DEBUG_REG1*/ + AV_SCRATCH_N /*user_data_flags*/ +}; +#endif static void check_timer_func(unsigned long arg); static void vavs_work(struct work_struct *work); @@ -129,17 +158,21 @@ static u32 dec_control = DEC_CONTROL_FLAG_FORCE_2500_1080P_INTERLACE; #define VPP_VD1_POSTBLEND (1 << 10) static int debug; -#define debug_flag debug static unsigned int debug_mask = 0xff; /*for debug*/ /* udebug_flag: bit 0, enable ucode print - bit 1, enable ucode detail print + bit 1, enable ucode more print + bit 3, enable ucdode detail print bit [31:16] not 0, pos to dump lmem bit 2, pop bits to lmem bit [11:8], pre-pop bits for alignment (when bit 2 is 1) + + avs only: + bit [8], disable empty muitl-instance handling + bit [9], enable writting of VC1_CONTROL_REG in ucode */ static u32 udebug_flag; /* @@ -157,16 +190,35 @@ static u32 udebug_pause_val; static u32 udebug_pause_decode_idx; +static u32 udebug_pause_ins_id; + static u32 force_fps; +#ifdef DEBUG_MULTI_FRAME_INS +static u32 delay; +#endif + static u32 step; +static u32 start_decoding_delay; + #define AVS_DEV_NUM 9 static unsigned int max_decode_instance_num = AVS_DEV_NUM; static unsigned int max_process_time[AVS_DEV_NUM]; static unsigned int max_get_frame_interval[AVS_DEV_NUM]; +static unsigned int run_count[AVS_DEV_NUM]; +static unsigned int ins_udebug_flag[AVS_DEV_NUM]; +#ifdef DEBUG_MULTI_FRAME_INS +static unsigned int max_run_count[AVS_DEV_NUM]; +#endif +/* +error_handle_policy: +*/ +static unsigned int error_handle_policy = 3; -static unsigned int decode_timeout_val = 100; +static u32 again_threshold = 0; /*0x40;*/ + +static unsigned int decode_timeout_val = 200; static unsigned int start_decode_buf_level = 0x8000; /******************************** @@ -181,11 +233,6 @@ static int firmware_sel; static int disable_longcabac_trans = 1; -int avs_get_debug_flag(void) -{ - return debug_flag; -} - static struct vframe_s *vavs_vf_peek(void *); static struct vframe_s *vavs_vf_get(void *); static void vavs_vf_put(struct vframe_s *, void *); @@ -211,8 +258,11 @@ static void *mm_blk_handle; static struct vframe_provider_s vavs_vf_prov; #define VF_BUF_NUM_MAX 16 +#ifdef DEBUG_MULTI_FRAME_INS +#define WORKSPACE_SIZE (16 * SZ_1M) +#else #define WORKSPACE_SIZE (4 * SZ_1M) - +#endif #ifdef AVSP_LONG_CABAC #define MAX_BMMU_BUFFER_NUM (VF_BUF_NUM_MAX + 2) #define WORKSPACE_SIZE_A (MAX_CODED_FRAME_SIZE + LOCAL_HEAP_SIZE) @@ -223,7 +273,8 @@ static struct vframe_provider_s vavs_vf_prov; #define RV_AI_BUFF_START_ADDR 0x01a00000 #define LONG_CABAC_RV_AI_BUFF_START_ADDR 0x00000000 -static u32 vf_buf_num = 4; +/* 4 buffers not enough for multi inc*/ +static u32 vf_buf_num = 8; /*static u32 vf_buf_num_used;*/ static u32 canvas_base = 128; #ifdef NV21 @@ -327,6 +378,21 @@ static const u32 frame_rate_tab[16] = { }; #define DECODE_BUFFER_NUM_MAX VF_BUF_NUM_MAX +#define PIC_PTS_NUM 64 +struct buf_pool_s { + unsigned detached; + struct vframe_s vf; +}; + +#define buf_of_vf(vf) container_of(vf, struct buf_pool_s, vf) + +struct pic_pts_s { + u32 pts; + u64 pts64; + u64 timestamp; + unsigned short decode_pic_count; +}; + struct vdec_avs_hw_s { spinlock_t lock; unsigned char m_ins_flag; @@ -334,7 +400,7 @@ struct vdec_avs_hw_s { DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE); DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE); DECLARE_KFIFO(recycle_q, struct vframe_s *, VF_POOL_SIZE); - struct vframe_s vfpool[VF_POOL_SIZE]; + struct buf_pool_s vfpool[VF_POOL_SIZE]; s32 vfbuf_use[VF_BUF_NUM_MAX]; unsigned char again_flag; unsigned char recover_flag; @@ -351,6 +417,9 @@ struct vdec_avs_hw_s { u32 total_frame; u32 next_pts; unsigned char throw_pb_flag; + struct pic_pts_s pic_pts[PIC_PTS_NUM]; + int pic_pts_wr_pos; + #ifdef DEBUG_PTS u32 pts_hit; u32 pts_missed; @@ -380,6 +449,7 @@ struct vdec_avs_hw_s { u8 reset_decode_flag; u32 display_frame_count; u32 buf_status; + u32 pre_parser_wr_ptr; /* buffer_status &= ~buf_recycle_status */ @@ -421,6 +491,9 @@ struct vdec_avs_hw_s { u32 reg_anc2_canvas_addr; u32 reg_anc0_canvas_addr; u32 reg_anc1_canvas_addr; + u32 reg_anc3_canvas_addr; + u32 reg_anc4_canvas_addr; + u32 reg_anc5_canvas_addr; u32 slice_ver_pos_pic_type; u32 vc1_control_reg; u32 avs_co_mb_wr_addr; @@ -458,7 +531,6 @@ struct vdec_avs_hw_s { void (*vdec_cb)(struct vdec_s *, void *); void *vdec_cb_arg; /* for error handling */ - u32 first_i_frame_ready; u32 run_count; u32 not_run_ready; u32 input_empty; @@ -470,6 +542,9 @@ struct vdec_avs_hw_s { u32 buffer_not_ready; int frameinfo_enable; struct firmware_s *fw; + u32 old_udebug_flag; + u32 decode_status_skip_pic_done_flag; + u32 decode_decode_cont_start_code; }; static void reset_process_time(struct vdec_avs_hw_s *hw); @@ -490,11 +565,12 @@ struct vdec_avs_hw_s *ghw; #define DEC_RESULT_GET_DATA_RETRY 7 #define DEC_RESULT_USERDATA 8 -#define DECODE_ID(hw) (hw->m_ins_flag? 0 : hw_to_vdec(hw)->id) +#define DECODE_ID(hw) (hw->m_ins_flag? hw_to_vdec(hw)->id : 0) #define PRINT_FLAG_ERROR 0x0 #define PRINT_FLAG_RUN_FLOW 0X0001 #define PRINT_FLAG_DECODING 0x0002 +#define PRINT_FLAG_PTS 0x0004 #define PRINT_FLAG_VFRAME_DETAIL 0x0010 #define PRINT_FLAG_VLD_DETAIL 0x0020 #define PRINT_FLAG_DEC_DETAIL 0x0040 @@ -504,8 +580,25 @@ struct vdec_avs_hw_s *ghw; #define PRINT_FRAMEBASE_DATA 0x0400 #define PRINT_FLAG_PARA_DATA 0x1000 #define DEBUG_FLAG_PREPARE_MORE_INPUT 0x2000 +#define DEBUG_FLAG_PRINT_REG 0x4000 #define DEBUG_FLAG_DISABLE_TIMEOUT 0x10000 #define DEBUG_WAIT_DECODE_DONE_WHEN_STOP 0x20000 +#define DEBUG_PIC_DONE_WHEN_UCODE_PAUSE 0x40000 + + +#undef DEBUG_REG +#ifdef DEBUG_REG +static void WRITE_VREG_DBG2(unsigned adr, unsigned val) +{ + if (debug & DEBUG_FLAG_PRINT_REG) + pr_info("%s(%x, %x)\n", __func__, adr, val); + if (adr != 0) + WRITE_VREG(adr, val); +} + +#undef WRITE_VREG +#define WRITE_VREG WRITE_VREG_DBG2 +#endif #undef pr_info #define pr_info printk @@ -515,7 +608,9 @@ static int debug_print(struct vdec_avs_hw_s *hw, #define AVS_PRINT_BUF 256 unsigned char buf[AVS_PRINT_BUF]; int len = 0; - int index = hw->m_ins_flag ? DECODE_ID(hw) : 0; + int index = 0; + if (hw) + index = hw->m_ins_flag ? DECODE_ID(hw) : 0; if (hw == NULL || (flag == 0) || ((debug_mask & @@ -527,7 +622,7 @@ static int debug_print(struct vdec_avs_hw_s *hw, if (hw) len = sprintf(buf, "[%d]", index); vsnprintf(buf + len, AVS_PRINT_BUF - len, fmt, args); - pr_debug("%s", buf); + pr_info("%s", buf); va_end(args); } return 0; @@ -538,7 +633,9 @@ static int debug_print_cont(struct vdec_avs_hw_s *hw, { unsigned char buf[AVS_PRINT_BUF]; int len = 0; - int index = hw->m_ins_flag ? DECODE_ID(hw) : 0; + int index = 0; + if (hw) + index = hw->m_ins_flag ? DECODE_ID(hw) : 0; if (hw == NULL || (flag == 0) || ((debug_mask & @@ -554,6 +651,82 @@ static int debug_print_cont(struct vdec_avs_hw_s *hw, return 0; } +static void avs_pts_check_in(struct vdec_avs_hw_s *hw, + unsigned short decode_pic_count, struct vframe_chunk_s *chunk) +{ + if (chunk) + debug_print(hw, PRINT_FLAG_PTS, + "%s %d (wr pos %d), pts %d pts64 %ld timestamp %ld\n", + __func__, decode_pic_count, hw->pic_pts_wr_pos, + chunk->pts, (u64)(chunk->pts64), (u64)(chunk->timestamp)); + else + debug_print(hw, PRINT_FLAG_PTS, + "%s %d, chunk is null\n", + __func__, decode_pic_count); + + if (chunk) { + hw->pic_pts[hw->pic_pts_wr_pos].pts = chunk->pts; + hw->pic_pts[hw->pic_pts_wr_pos].pts64 = chunk->pts64; + hw->pic_pts[hw->pic_pts_wr_pos].timestamp = chunk->timestamp; + } else { + hw->pic_pts[hw->pic_pts_wr_pos].pts = 0; + hw->pic_pts[hw->pic_pts_wr_pos].pts64 = 0; + hw->pic_pts[hw->pic_pts_wr_pos].timestamp = 0; + } + hw->pic_pts[hw->pic_pts_wr_pos].decode_pic_count + = decode_pic_count; + hw->pic_pts_wr_pos++; + if (hw->pic_pts_wr_pos >= PIC_PTS_NUM) + hw->pic_pts_wr_pos = 0; + return; +} + +static void clear_pts_buf(struct vdec_avs_hw_s *hw) +{ + int i; + debug_print(hw, PRINT_FLAG_PTS, + "%s\n", __func__); + hw->pic_pts_wr_pos = 0; + for (i = 0; i < PIC_PTS_NUM; i++) { + hw->pic_pts[hw->pic_pts_wr_pos].pts = 0; + hw->pic_pts[hw->pic_pts_wr_pos].pts64 = 0; + hw->pic_pts[hw->pic_pts_wr_pos].timestamp = 0; + hw->pic_pts[hw->pic_pts_wr_pos].decode_pic_count = 0; + } +} + +static int set_vframe_pts(struct vdec_avs_hw_s *hw, + unsigned short decode_pic_count, struct vframe_s *vf) +{ + int i; + int ret = -1; + for (i = 0; i < PIC_PTS_NUM; i++) { + if (hw->pic_pts[i].decode_pic_count == decode_pic_count) { + vf->pts = hw->pic_pts[i].pts; + vf->pts_us64 = hw->pic_pts[i].pts64; + vf->timestamp = hw->pic_pts[i].timestamp; + ret = 0; + debug_print(hw, PRINT_FLAG_PTS, + "%s %d (rd pos %d), pts %d pts64 %ld timestamp %ld\n", + __func__, decode_pic_count, i, + vf->pts, vf->pts_us64, vf->timestamp); + + break; + } + } + return ret; +} + +static void avs_vf_notify_receiver(struct vdec_avs_hw_s *hw, + const char *provider_name, int event_type, void *data) +{ + if (hw->m_ins_flag) + vf_notify_receiver(hw_to_vdec(hw)->vf_provider_name, + event_type, data); + else + vf_notify_receiver(provider_name, event_type, data); +} + static void set_frame_info(struct vdec_avs_hw_s *hw, struct vframe_s *vf, unsigned int *duration) { @@ -619,6 +792,8 @@ static void set_frame_info(struct vdec_avs_hw_s *hw, struct vframe_s *vf, /*vf->ratio_control |= DISP_RATIO_FORCECONFIG | DISP_RATIO_KEEPRATIO; */ vf->flag = 0; + buf_of_vf(vf)->detached = 0; + } #ifdef ENABLE_USER_DATA @@ -735,6 +910,27 @@ static u8 UserDataHandler(struct vdec_avs_hw_s *hw) } #endif + +static inline void avs_update_gvs(struct vdec_avs_hw_s *hw) +{ + if (hw->gvs->frame_height != hw->frame_height) { + hw->gvs->frame_width = hw->frame_width; + hw->gvs->frame_height = hw->frame_height; + } + if (hw->gvs->frame_dur != hw->frame_dur) { + hw->gvs->frame_dur = hw->frame_dur; + if (hw->frame_dur != 0) + hw->gvs->frame_rate = 96000 / hw->frame_dur; + else + hw->gvs->frame_rate = -1; + } + + hw->gvs->status = hw->stat; + hw->gvs->error_count = READ_VREG(AV_SCRATCH_C); + hw->gvs->drop_frame_count = hw->drop_frame_count; + +} + #ifdef HANDLE_AVS_IRQ static irqreturn_t vavs_isr(int irq, void *dev_id) #else @@ -742,7 +938,7 @@ static void vavs_isr(void) #endif { u32 reg; - struct vframe_s *vf; + struct vframe_s *vf = NULL; u32 dur; u32 repeat_count; u32 picture_type; @@ -755,7 +951,7 @@ static void vavs_isr(void) u32 buffer_status_debug; struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_s *)dev_id; - /*if (debug_flag & AVS_DEBUG_UCODE) { + /*if (debug & AVS_DEBUG_UCODE) { if (READ_VREG(AV_SCRATCH_E) != 0) { pr_info("dbg%x: %x\n", READ_VREG(AV_SCRATCH_E), READ_VREG(AV_SCRATCH_D)); @@ -766,9 +962,9 @@ static void vavs_isr(void) #define DEBUG_REG2 AV_SCRATCH_D debug_tag = READ_VREG(DEBUG_REG1); - buffer_status_debug = debug_tag >> 24; - debug_tag &= 0xffffff; - if (debug_tag & 0x10000) { + buffer_status_debug = debug_tag >> 16; + debug_tag &= 0xffff; + /* if (debug_tag & 0x10000) { int i; dma_sync_single_for_cpu( amports_get_dma_device(), @@ -807,24 +1003,46 @@ static void vavs_isr(void) reset_process_time(hw); else WRITE_VREG(DEBUG_REG1, 0); - } else if (debug_tag != 0) { + } else*/ if (debug_tag != 0) { debug_print(hw, 0, - "dbg%x: %x buffer_status 0x%x l/w/r %x %x %x bitcnt %x\n", + "dbg%x: %x buffer_status 0x%x l/w/r %x %x %x bitcnt %x AVAIL %x\n", debug_tag, READ_VREG(DEBUG_REG2), buffer_status_debug, READ_VREG(VLD_MEM_VIFIFO_LEVEL), READ_VREG(VLD_MEM_VIFIFO_WP), READ_VREG(VLD_MEM_VIFIFO_RP), - READ_VREG(VIFF_BIT_CNT)); + READ_VREG(VIFF_BIT_CNT), + READ_VREG(VLD_MEM_VIFIFO_BYTES_AVAIL)); + if (((udebug_pause_pos & 0xffff) == (debug_tag & 0xffff)) && (udebug_pause_decode_idx == 0 || udebug_pause_decode_idx == hw->decode_pic_count) && (udebug_pause_val == 0 || - udebug_pause_val == READ_VREG(DEBUG_REG2))) { + udebug_pause_val == READ_VREG(DEBUG_REG2)) && + (udebug_pause_ins_id == 0 || + DECODE_ID(hw) == (udebug_pause_ins_id -1))) { udebug_pause_pos &= 0xffff; hw->ucode_pause_pos = udebug_pause_pos; + if (debug & DEBUG_PIC_DONE_WHEN_UCODE_PAUSE) { + hw->decode_pic_count++; + if ((hw->decode_pic_count & 0xffff) == 0) { + /*make ucode do not handle it as first picture*/ + hw->decode_pic_count++; + } + reset_process_time(hw); + hw->dec_result = DEC_RESULT_DONE; + amvdec_stop(); + vavs_save_regs(hw); + debug_print(hw, PRINT_FLAG_DECODING, + "%s ucode pause, force done, decode_pic_count = %d, bit_cnt=0x%x\n", + __func__, + hw->decode_pic_count, + READ_VREG(VIFF_BIT_CNT)); + vdec_schedule_work(&hw->work); + return IRQ_HANDLED; + } } if (hw->ucode_pause_pos) reset_process_time(hw); @@ -856,12 +1074,13 @@ static void vavs_isr(void) #endif reg = READ_VREG(AVS_BUFFEROUT); if (reg) { - if (debug_flag & AVS_DEBUG_PRINT) - pr_info("AVS_BUFFEROUT=%x\n", reg); + unsigned short decode_pic_count + = READ_VREG(DECODE_PIC_COUNT); + debug_print(hw, PRINT_FLAG_DECODING, "AVS_BUFFEROUT=0x%x decode_pic_count %d\n", + reg, decode_pic_count); if (pts_by_offset) { offset = READ_VREG(AVS_OFFSET_REG); - if (debug_flag & AVS_DEBUG_PRINT) - pr_info("AVS OFFSET=%x\n", offset); + debug_print(hw, PRINT_FLAG_DECODING, "AVS OFFSET=%x\n", offset); if (pts_lookup_offset_us64(PTS_TYPE_VIDEO, offset, &pts, &frame_size, 0, &pts_us64) == 0) { @@ -877,6 +1096,11 @@ static void vavs_isr(void) } repeat_count = READ_VREG(AVS_REPEAT_COUNT); +#ifdef USE_DYNAMIC_BUF_NUM + buffer_index = + ((reg & 0x7) + + (((reg >> 8) & 0x3) << 3) - 1) & 0x1f; +#else if (firmware_sel == 0) buffer_index = ((reg & 0x7) + @@ -884,7 +1108,7 @@ static void vavs_isr(void) else buffer_index = ((reg & 0x7) - 1) & 3; - +#endif picture_type = (reg >> 3) & 7; #ifdef DEBUG_PTS if (picture_type == I_PICTURE) { @@ -914,10 +1138,9 @@ static void vavs_isr(void) } else if (reg & INTERLACE_FLAG || force_interlaced_frame) { /* interlace */ hw->throw_pb_flag = 0; - if (debug_flag & AVS_DEBUG_PRINT) { - pr_info("interlace, picture type %d\n", + debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, + "interlace, picture type %d\n", picture_type); - } if (kfifo_get(&hw->newframe_q, &vf) == 0) { pr_info @@ -989,10 +1212,9 @@ static void vavs_isr(void) index2canvas(buffer_index); vf->type_original = vf->type; - if (debug_flag & AVS_DEBUG_PRINT) { - pr_info("buffer_index %d, canvas addr %x\n", + debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, + "buffer_index %d, canvas addr %x\n", buffer_index, vf->canvas0Addr); - } vf->pts_us64 = (pts_valid) ? pts_us64 : 0; hw->vfbuf_use[buffer_index]++; vf->mem_handle = @@ -1000,9 +1222,12 @@ static void vavs_isr(void) hw->mm_blk_handle, buffer_index); + if (hw->m_ins_flag && vdec_frame_based(hw_to_vdec(hw))) + set_vframe_pts(hw, decode_pic_count, vf); + kfifo_put(&hw->display_q, (const struct vframe_s *)vf); - vf_notify_receiver(PROVIDER_NAME, + avs_vf_notify_receiver(hw, PROVIDER_NAME, VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); @@ -1068,19 +1293,21 @@ static void vavs_isr(void) hw->mm_blk_handle, buffer_index); + if (hw->m_ins_flag && vdec_frame_based(hw_to_vdec(hw))) + set_vframe_pts(hw, decode_pic_count, vf); + kfifo_put(&hw->display_q, (const struct vframe_s *)vf); - vf_notify_receiver(PROVIDER_NAME, + avs_vf_notify_receiver(hw, PROVIDER_NAME, VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); hw->total_frame++; } else { /* progressive */ hw->throw_pb_flag = 0; - if (debug_flag & AVS_DEBUG_PRINT) { - pr_info("progressive picture type %d\n", + debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, + "progressive picture type %d\n", picture_type); - } if (kfifo_get(&hw->newframe_q, &vf) == 0) { pr_info ("fatal error, no available buffer slot."); @@ -1145,27 +1372,31 @@ static void vavs_isr(void) vf->type_original = vf->type; vf->pts_us64 = (pts_valid) ? pts_us64 : 0; - if (debug_flag & AVS_DEBUG_PRINT) { - pr_info("buffer_index %d, canvas addr %x\n", + debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, + "buffer_index %d, canvas addr %x\n", buffer_index, vf->canvas0Addr); - } hw->vfbuf_use[buffer_index]++; vf->mem_handle = decoder_bmmu_box_get_mem_handle( hw->mm_blk_handle, buffer_index); + + if (hw->m_ins_flag && vdec_frame_based(hw_to_vdec(hw))) + set_vframe_pts(hw, decode_pic_count, vf); + kfifo_put(&hw->display_q, (const struct vframe_s *)vf); - vf_notify_receiver(PROVIDER_NAME, + avs_vf_notify_receiver(hw, PROVIDER_NAME, VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); hw->total_frame++; } /*count info*/ - hw->gvs->frame_dur = hw->frame_dur; vdec_count_info(hw->gvs, 0, offset); + avs_update_gvs(hw); + vdec_fill_vdec_frame(hw_to_vdec(hw), NULL, hw->gvs, vf, 0); /* pr_info("PicType = %d, PTS = 0x%x\n", * picture_type, vf->pts); @@ -1181,14 +1412,24 @@ static void vavs_isr(void) if (hw->dec_result == DEC_RESULT_DONE || hw->dec_result == DEC_RESULT_AGAIN) { debug_print(hw, PRINT_FLAG_DECODING, - "%s !!! decode_status 0x%x, buf_status 0x%x, dec_result = 0x%x, decode_pic_count = %d\n", - __func__, decode_status, + "%s !!! READ_VREG(DECODE_STATUS) = 0x%x, decode_status 0x%x, buf_status 0x%x, dec_result = 0x%x, decode_pic_count = %d bit_cnt=0x%x\n", + __func__, status_reg, decode_status, hw->buf_status, - hw->dec_result, hw->decode_pic_count); + hw->dec_result, hw->decode_pic_count, + READ_VREG(VIFF_BIT_CNT)); return IRQ_HANDLED; - } else if (decode_status == DECODE_STATUS_PIC_DONE) { - hw->buf_status = (status_reg >> 8) & 0xffff; + } else if (decode_status == DECODE_STATUS_PIC_DONE || + decode_status == DECODE_STATUS_SKIP_PIC_DONE) { + hw->buf_status = (status_reg >> 16) & 0xffff; + if (decode_status == DECODE_STATUS_SKIP_PIC_DONE) { + hw->decode_status_skip_pic_done_flag = 1; + hw->decode_decode_cont_start_code = (status_reg >> 8) & 0xff; + } hw->decode_pic_count++; + if ((hw->decode_pic_count & 0xffff) == 0) { + /*make ucode do not handle it as first picture*/ + hw->decode_pic_count++; + } reset_process_time(hw); hw->dec_result = DEC_RESULT_DONE; #if DEBUG_MULTI_FLAG == 1 @@ -1198,27 +1439,41 @@ static void vavs_isr(void) #endif vavs_save_regs(hw); debug_print(hw, PRINT_FLAG_DECODING, - "%s DECODE_STATUS_PIC_DONE, decode_status 0x%x, buf_status 0x%x, dec_result = 0x%x, decode_pic_count = %d\n", - __func__, decode_status, + "%s %s, READ_VREG(DECODE_STATUS) = 0x%x, decode_status 0x%x, buf_status 0x%x, dec_result = 0x%x, decode_pic_count = %d, bit_cnt=0x%x\n", + __func__, + (decode_status == DECODE_STATUS_PIC_DONE) ? + "DECODE_STATUS_PIC_DONE" : "DECODE_STATUS_SKIP_PIC_DONE", + status_reg, decode_status, hw->buf_status, - hw->dec_result, hw->decode_pic_count); + hw->dec_result, hw->decode_pic_count, + READ_VREG(VIFF_BIT_CNT)); vdec_schedule_work(&hw->work); return IRQ_HANDLED; } else if (decode_status == DECODE_STATUS_DECODE_BUF_EMPTY || decode_status == DECODE_STATUS_SEARCH_BUF_EMPTY) { - hw->buf_status = (status_reg >> 8) & 0xffff; + hw->buf_status = (status_reg >> 16) & 0xffff; reset_process_time(hw); - hw->dec_result = DEC_RESULT_AGAIN; #if DEBUG_MULTI_FLAG == 1 WRITE_VREG(DECODE_STATUS, 0); #else amvdec_stop(); #endif + if (vdec_frame_based(hw_to_vdec(hw))) { + hw->dec_result = DEC_RESULT_DONE; + if (hw->decode_pic_count == 0) { + hw->decode_pic_count++; + } + vavs_save_regs(hw); + } else + hw->dec_result = DEC_RESULT_AGAIN; + debug_print(hw, PRINT_FLAG_DECODING, - "%s BUF_EMPTY, decode_status 0x%x, buf_status 0x%x, dec_result = 0x%x, decode_pic_count = %d\n", - __func__, decode_status, + "%s BUF_EMPTY, READ_VREG(DECODE_STATUS) = 0x%x, decode_status 0x%x, buf_status 0x%x, scratch_8 (AVS_BUFFERIN) 0x%x, dec_result = 0x%x, decode_pic_count = %d, bit_cnt=0x%x\n", + __func__, status_reg, decode_status, hw->buf_status, - hw->dec_result, hw->decode_pic_count); + hw->reg_scratch_8, + hw->dec_result, hw->decode_pic_count, + READ_VREG(VIFF_BIT_CNT)); vdec_schedule_work(&hw->work); return IRQ_HANDLED; } @@ -1299,12 +1554,13 @@ static struct vframe_s *vavs_vf_get(void *op_arg) } debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, - "%s, index = %d, w %d h %d, type 0x%x\n", + "%s, index = %d, w %d h %d, type 0x%x detached %d\n", __func__, vf->index, vf->width, vf->height, - vf->type); + vf->type, + buf_of_vf(vf)->detached); } return vf; } @@ -1322,18 +1578,19 @@ static void vavs_vf_put(struct vframe_s *vf, void *op_arg) if (vf) { hw->put_num++; debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, - "%s, index = %d, w %d h %d, type 0x%x\n", + "%s, index = %d, w %d h %d, type 0x%x detached 0x%x\n", __func__, vf->index, vf->width, vf->height, - vf->type); + vf->type, + buf_of_vf(vf)->detached); } if (hw->recover_flag) return; for (i = 0; i < VF_POOL_SIZE; i++) { - if (vf == &hw->vfpool[i]) + if (vf == &hw->vfpool[i].vf) break; } if (i < VF_POOL_SIZE) @@ -1391,14 +1648,12 @@ int vavs_set_isreset(struct vdec_s *vdec, int isreset) static int vavs_vdec_info_init(struct vdec_avs_hw_s *hw) { - pr_info("%s %d\n", __func__, __LINE__); hw->gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL); if (NULL == hw->gvs) { pr_info("the struct of vdec status malloc failed.\n"); return -ENOMEM; } - pr_info("%s %d\n", __func__, __LINE__); return 0; } @@ -1415,7 +1670,6 @@ static int vavs_canvas_init(struct vdec_avs_hw_s *hw) if (hw->m_ins_flag) vdec = hw_to_vdec(hw); - hw->vf_buf_num_used = vf_buf_num; if (buf_size <= 0x00400000) { /* SD only */ canvas_width = 768; @@ -1538,10 +1792,9 @@ static int vavs_canvas_init(struct vdec_avs_hw_s *hw) CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); #endif - if (debug_flag & AVS_DEBUG_PRINT) { - pr_info("canvas config %d, addr %p\n", i, + debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, + "canvas config %d, addr %p\n", i, (void *)buf_start); - } } } return 0; @@ -1577,7 +1830,7 @@ void vavs_recover(struct vdec_avs_hw_s *hw) WRITE_VREG(AV_SCRATCH_1, hw->vf_buf_num_used); } else { int ii; - +#ifndef USE_DYNAMIC_BUF_NUM for (ii = 0; ii < 4; ii++) { WRITE_VREG(AV_SCRATCH_0 + ii, (canvas_base + canvas_num * ii) | @@ -1587,6 +1840,19 @@ void vavs_recover(struct vdec_avs_hw_s *hw) << 16) ); } +#else + for (ii = 0; ii < hw->vf_buf_num_used; ii += 2) { + WRITE_VREG(buf_spec_reg[ii >> 1], + (canvas_base + canvas_num * ii) | + ((canvas_base + canvas_num * ii + 1) + << 8) | + ((canvas_base + canvas_num * ii + 2) + << 16) | + ((canvas_base + canvas_num * ii + 3) + << 24) + ); + } +#endif } /* notify ucode the buffer offset */ @@ -1595,7 +1861,9 @@ void vavs_recover(struct vdec_avs_hw_s *hw) /* disable PSCALE for hardware sharing */ WRITE_VREG(PSCALE_CTRL, 0); +#ifndef USE_DYNAMIC_BUF_NUM WRITE_VREG(AVS_SOS_COUNT, 0); +#endif WRITE_VREG(AVS_BUFFERIN, 0); WRITE_VREG(AVS_BUFFEROUT, 0); if (error_recovery_mode) @@ -1607,7 +1875,7 @@ void vavs_recover(struct vdec_avs_hw_s *hw) /* enable mailbox interrupt */ WRITE_VREG(ASSIST_MBOX1_MASK, 1); -#if 1 /* def DEBUG_UCODE */ +#ifndef USE_DYNAMIC_BUF_NUM /* def DEBUG_UCODE */ WRITE_VREG(AV_SCRATCH_D, 0); #endif @@ -1665,37 +1933,44 @@ static void vavs_save_regs(struct vdec_avs_hw_s *hw) hw->reg_viff_bit_cnt = READ_VREG(VIFF_BIT_CNT); hw->reg_canvas_addr = READ_VREG(REC_CANVAS_ADDR); - hw->reg_dbkr_canvas_addr = READ_VREG(DBKR_CANVAS_ADDR); - hw->reg_dbkw_canvas_addr = READ_VREG(DBKW_CANVAS_ADDR); - hw->reg_anc2_canvas_addr = READ_VREG(ANC2_CANVAS_ADDR); - hw->reg_anc0_canvas_addr = READ_VREG(ANC0_CANVAS_ADDR); - hw->reg_anc1_canvas_addr = READ_VREG(ANC1_CANVAS_ADDR); - - hw->slice_ver_pos_pic_type = READ_VREG(SLICE_VER_POS_PIC_TYPE); - - hw->vc1_control_reg = READ_VREG(VC1_CONTROL_REG); - hw->avs_co_mb_wr_addr = READ_VREG(AVS_CO_MB_WR_ADDR); - hw->slice_start_byte_01 = READ_VREG(SLICE_START_BYTE_01); - hw->slice_start_byte_23 = READ_VREG(SLICE_START_BYTE_23); - hw->vcop_ctrl_reg = READ_VREG(VCOP_CTRL_REG); - hw->iqidct_control = READ_VREG(IQIDCT_CONTROL); - hw->rv_ai_mb_count = READ_VREG(RV_AI_MB_COUNT); - hw->slice_qp = READ_VREG(SLICE_QP); - - hw->dc_scaler = READ_VREG(DC_SCALER); - hw->avsp_iq_wq_param_01 = READ_VREG(AVSP_IQ_WQ_PARAM_01); - hw->avsp_iq_wq_param_23 = READ_VREG(AVSP_IQ_WQ_PARAM_23); - hw->avsp_iq_wq_param_45 = READ_VREG(AVSP_IQ_WQ_PARAM_45); - hw->avs_co_mb_rd_addr = READ_VREG(AVS_CO_MB_RD_ADDR); - hw->dblk_mb_wid_height = READ_VREG(DBLK_MB_WID_HEIGHT); - hw->mc_pic_w_h = READ_VREG(MC_PIC_W_H); - hw->avs_co_mb_rw_ctl = READ_VREG(AVS_CO_MB_RW_CTL); - - hw->vld_decode_control = READ_VREG(VLD_DECODE_CONTROL); + hw->reg_dbkr_canvas_addr = READ_VREG(DBKR_CANVAS_ADDR); + hw->reg_dbkw_canvas_addr = READ_VREG(DBKW_CANVAS_ADDR); + hw->reg_anc2_canvas_addr = READ_VREG(ANC2_CANVAS_ADDR); + hw->reg_anc0_canvas_addr = READ_VREG(ANC0_CANVAS_ADDR); + hw->reg_anc1_canvas_addr = READ_VREG(ANC1_CANVAS_ADDR); + hw->reg_anc3_canvas_addr = READ_VREG(ANC3_CANVAS_ADDR); + hw->reg_anc4_canvas_addr = READ_VREG(ANC4_CANVAS_ADDR); + hw->reg_anc5_canvas_addr = READ_VREG(ANC5_CANVAS_ADDR); + + hw->slice_ver_pos_pic_type = READ_VREG(SLICE_VER_POS_PIC_TYPE); + + hw->vc1_control_reg = READ_VREG(VC1_CONTROL_REG); + hw->avs_co_mb_wr_addr = READ_VREG(AVS_CO_MB_WR_ADDR); + hw->slice_start_byte_01 = READ_VREG(SLICE_START_BYTE_01); + hw->slice_start_byte_23 = READ_VREG(SLICE_START_BYTE_23); + hw->vcop_ctrl_reg = READ_VREG(VCOP_CTRL_REG); + hw->iqidct_control = READ_VREG(IQIDCT_CONTROL); + hw->rv_ai_mb_count = READ_VREG(RV_AI_MB_COUNT); + hw->slice_qp = READ_VREG(SLICE_QP); + + hw->dc_scaler = READ_VREG(DC_SCALER); + hw->avsp_iq_wq_param_01 = READ_VREG(AVSP_IQ_WQ_PARAM_01); + hw->avsp_iq_wq_param_23 = READ_VREG(AVSP_IQ_WQ_PARAM_23); + hw->avsp_iq_wq_param_45 = READ_VREG(AVSP_IQ_WQ_PARAM_45); + hw->avs_co_mb_rd_addr = READ_VREG(AVS_CO_MB_RD_ADDR); + hw->dblk_mb_wid_height = READ_VREG(DBLK_MB_WID_HEIGHT); + hw->mc_pic_w_h = READ_VREG(MC_PIC_W_H); + hw->avs_co_mb_rw_ctl = READ_VREG(AVS_CO_MB_RW_CTL); + + hw->vld_decode_control = READ_VREG(VLD_DECODE_CONTROL); } static void vavs_restore_regs(struct vdec_avs_hw_s *hw) { + debug_print(hw, PRINT_FLAG_DECODING, + "%s scratch_8 (AVS_BUFFERIN) 0x%x, decode_pic_count = %d\n", + __func__, hw->reg_scratch_8, hw->decode_pic_count); + WRITE_VREG(AV_SCRATCH_0, hw->reg_scratch_0); WRITE_VREG(AV_SCRATCH_1, hw->reg_scratch_1); WRITE_VREG(AV_SCRATCH_2, hw->reg_scratch_2); @@ -1725,6 +2000,9 @@ static void vavs_restore_regs(struct vdec_avs_hw_s *hw) WRITE_VREG(ANC2_CANVAS_ADDR, hw->reg_anc2_canvas_addr); WRITE_VREG(ANC0_CANVAS_ADDR, hw->reg_anc0_canvas_addr); WRITE_VREG(ANC1_CANVAS_ADDR, hw->reg_anc1_canvas_addr); + WRITE_VREG(ANC3_CANVAS_ADDR, hw->reg_anc3_canvas_addr); + WRITE_VREG(ANC4_CANVAS_ADDR, hw->reg_anc4_canvas_addr); + WRITE_VREG(ANC5_CANVAS_ADDR, hw->reg_anc5_canvas_addr); WRITE_VREG(SLICE_VER_POS_PIC_TYPE, hw->slice_ver_pos_pic_type); @@ -1789,15 +2067,28 @@ static int vavs_prot_init(struct vdec_avs_hw_s *hw) int i; if (hw->decode_pic_count == 0) { r = vavs_canvas_init(hw); +#ifndef USE_DYNAMIC_BUF_NUM for (i = 0; i < 4; i++) { WRITE_VREG(AV_SCRATCH_0 + i, hw->canvas_spec[i] ); } +#else + for (i = 0; i < hw->vf_buf_num_used; i += 2) { + WRITE_VREG(buf_spec_reg[i >> 1], + (hw->canvas_spec[i] & 0xffff) | + ((hw->canvas_spec[i + 1] & 0xffff) + << 16) + ); + debug_print(hw, PRINT_FLAG_DECODING, + "%s WRITE_VREG(0x%x, 0x%x)\n", + __func__, buf_spec_reg[i >> 1], READ_VREG(buf_spec_reg[i >> 1])); + } +#endif } else vavs_restore_regs(hw); - for (i = 0; i < 4; i++) { + for (i = 0; i < hw->vf_buf_num_used; i++) { canvas_config_ex(canvas_y(hw->canvas_spec[i]), hw->canvas_config[i][0].phy_addr, hw->canvas_config[i][0].width, @@ -1823,7 +2114,7 @@ static int vavs_prot_init(struct vdec_avs_hw_s *hw) WRITE_VREG(AV_SCRATCH_1, hw->vf_buf_num_used); } else { int ii; - +#ifndef USE_DYNAMIC_BUF_NUM for (ii = 0; ii < 4; ii++) { WRITE_VREG(AV_SCRATCH_0 + ii, (canvas_base + canvas_num * ii) | @@ -1833,6 +2124,19 @@ static int vavs_prot_init(struct vdec_avs_hw_s *hw) << 16) ); } +#else + for (ii = 0; ii < hw->vf_buf_num_used; ii += 2) { + WRITE_VREG(buf_spec_reg[ii >> 1], + (canvas_base + canvas_num * ii) | + ((canvas_base + canvas_num * ii + 1) + << 8) | + ((canvas_base + canvas_num * ii + 2) + << 16) | + ((canvas_base + canvas_num * ii + 3) + << 24) + ); + } +#endif /* *WRITE_VREG(AV_SCRATCH_0, 0x010100); *WRITE_VREG(AV_SCRATCH_1, 0x040403); @@ -1856,7 +2160,9 @@ static int vavs_prot_init(struct vdec_avs_hw_s *hw) WRITE_VREG(PSCALE_CTRL, 0); if (hw->decode_pic_count == 0) { +#ifndef USE_DYNAMIC_BUF_NUM WRITE_VREG(AVS_SOS_COUNT, 0); +#endif WRITE_VREG(AVS_BUFFERIN, 0); WRITE_VREG(AVS_BUFFEROUT, 0); } @@ -1869,7 +2175,7 @@ static int vavs_prot_init(struct vdec_avs_hw_s *hw) /* enable mailbox interrupt */ WRITE_VREG(ASSIST_MBOX1_MASK, 1); -#if 1 /* def DEBUG_UCODE */ +#ifndef USE_DYNAMIC_BUF_NUM /* def DEBUG_UCODE */ if (hw->decode_pic_count == 0) WRITE_VREG(AV_SCRATCH_D, 0); #endif @@ -1881,7 +2187,12 @@ static int vavs_prot_init(struct vdec_avs_hw_s *hw) #ifdef PIC_DC_NEED_CLEAR CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31); #endif + if (hw->m_ins_flag && start_decoding_delay > 0) + msleep(start_decoding_delay); + //pr_info("+++++++++++++++++++++++++++++++\n"); + //pr_info("+++++++++++++++++++++++++++++++\n"); + //pr_info("+++++++++++++++++++++++++++++++\n"); #ifdef AVSP_LONG_CABAC if (firmware_sel == 0) { WRITE_VREG(LONG_CABAC_DES_ADDR, es_write_addr_phy); @@ -1900,98 +2211,29 @@ static int vavs_prot_init(struct vdec_avs_hw_s *hw) if (hw->m_ins_flag) { if (vdec_frame_based(hw_to_vdec(hw))) WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_FRAMEBASE); - else - WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE); + else { + if (hw->decode_status_skip_pic_done_flag) { + WRITE_VREG(DECODE_CFG, hw->decode_decode_cont_start_code); + WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE_CONT); + } else + WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE); + } WRITE_VREG(DECODE_LMEM_BUF_ADR, hw->lmem_phy_addr); } else WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE); - //WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE); - WRITE_VREG(DECODE_STOP_POS, udebug_flag); - - return r; -} -#if DEBUG_MULTI_FLAG > 0 -static int vavs_prot_init_vld_only(struct vdec_avs_hw_s *hw) -{ - int r = 0; - /***************** reset vld **********************************/ - WRITE_VREG(POWER_CTL_VLD, 0x10); - WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 2, MEM_FIFO_CNT_BIT, 2); - WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 8, MEM_LEVEL_CNT_BIT, 6); - /*************************************************************/ - if (hw->m_ins_flag) { - int i; - if (hw->decode_pic_count == 0) { - r = vavs_canvas_init(hw); - for (i = 0; i < 4; i++) { - WRITE_VREG(AV_SCRATCH_0 + i, - hw->canvas_spec[i] - ); - } - } else - vavs_restore_regs(hw); - - for (i = 0; i < 4; i++) { - canvas_config_ex(canvas_y(hw->canvas_spec[i]), - hw->canvas_config[i][0].phy_addr, - hw->canvas_config[i][0].width, - hw->canvas_config[i][0].height, - CANVAS_ADDR_NOWRAP, - hw->canvas_config[i][0].block_mode, - 0); - - canvas_config_ex(canvas_u(hw->canvas_spec[i]), - hw->canvas_config[i][1].phy_addr, - hw->canvas_config[i][1].width, - hw->canvas_config[i][1].height, - CANVAS_ADDR_NOWRAP, - hw->canvas_config[i][1].block_mode, - 0); - } + if (ins_udebug_flag[DECODE_ID(hw)] && + (ins_udebug_flag[DECODE_ID(hw)] >> 16) == hw->decode_pic_count) { + WRITE_VREG(DECODE_STOP_POS, + ins_udebug_flag[DECODE_ID(hw)] & 0xffff); } - /* notify ucode the buffer offset */ -#if DEBUG_MULTI_FLAG == 0 - /* disable PSCALE for hardware sharing */ - WRITE_VREG(PSCALE_CTRL, 0); - - if (hw->decode_pic_count == 0) { - WRITE_VREG(AVS_SOS_COUNT, 0); - WRITE_VREG(AVS_BUFFERIN, 0); - WRITE_VREG(AVS_BUFFEROUT, 0); - } - if (error_recovery_mode) - WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 0); else - WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 1); - /* clear mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - - /* enable mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_MASK, 1); - -#ifdef NV21 - SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); -#endif - -#ifdef PIC_DC_NEED_CLEAR - CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31); -#endif -#endif - if (hw->m_ins_flag) { - if (vdec_frame_based(hw_to_vdec(hw))) - WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_FRAMEBASE); - else - WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE); - WRITE_VREG(DECODE_LMEM_BUF_ADR, hw->lmem_phy_addr); - } else - WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE); - //WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE); - WRITE_VREG(DECODE_STOP_POS, udebug_flag); + WRITE_VREG(DECODE_STOP_POS, udebug_flag); + hw->old_udebug_flag = udebug_flag; return r; } -#endif + #ifdef AVSP_LONG_CABAC static unsigned char es_write_addr[MAX_CODED_FRAME_SIZE] __aligned(64); @@ -2000,6 +2242,8 @@ static void vavs_local_init(struct vdec_avs_hw_s *hw) { int i; + hw->vf_buf_num_used = vf_buf_num; + hw->vavs_ratio = hw->vavs_amstream_dec_info.ratio; hw->avi_flag = (unsigned long) hw->vavs_amstream_dec_info.param; @@ -2020,13 +2264,14 @@ static void vavs_local_init(struct vdec_avs_hw_s *hw) INIT_KFIFO(hw->newframe_q); for (i = 0; i < VF_POOL_SIZE; i++) { - const struct vframe_s *vf = &hw->vfpool[i]; + const struct vframe_s *vf = &hw->vfpool[i].vf; - hw->vfpool[i].index = vf_buf_num; - hw->vfpool[i].bufWidth = 1920; + hw->vfpool[i].vf.index = hw->vf_buf_num_used; + hw->vfpool[i].vf.bufWidth = 1920; + hw->vfpool[i].detached = 0; kfifo_put(&hw->newframe_q, vf); } - for (i = 0; i < vf_buf_num; i++) + for (i = 0; i < hw->vf_buf_num_used; i++) hw->vfbuf_use[i] = 0; /*cur_vfpool = vfpool;*/ @@ -2088,7 +2333,7 @@ static void vavs_local_reset(struct vdec_avs_hw_s *hw) pr_info("error, local reset\n"); amvdec_stop(); msleep(100); - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL); + avs_vf_notify_receiver(hw, PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL); vavs_local_init(hw); vavs_recover(hw); @@ -2122,7 +2367,7 @@ static void vavs_fatal_error_handler(struct work_struct *work) { struct vdec_avs_hw_s *hw = container_of(work, struct vdec_avs_hw_s, fatal_error_wd_work); - if (debug_flag & AVS_DEBUG_OLD_ERROR_HANDLE) { + if (debug & AVS_DEBUG_OLD_ERROR_HANDLE) { mutex_lock(&vavs_mutex); pr_info("vavs fatal error reset !\n"); amvdec_stop(); @@ -2148,7 +2393,7 @@ static void vavs_notify_work(struct work_struct *work) struct vdec_avs_hw_s *hw = container_of(work, struct vdec_avs_hw_s, notify_work); if (hw->fr_hint_status == VDEC_NEED_HINT) { - vf_notify_receiver(PROVIDER_NAME , + avs_vf_notify_receiver(hw, PROVIDER_NAME , VFRAME_EVENT_PROVIDER_FR_HINT , (void *)((unsigned long)hw->frame_dur)); hw->fr_hint_status = VDEC_HINTED; @@ -2166,7 +2411,7 @@ static void avs_set_clk(struct work_struct *work) hw->saved_resolution = hw->frame_width * hw->frame_height * fps; if (firmware_sel == 0 && - (debug_flag & AVS_DEBUG_USE_FULL_SPEED)) { + (debug & AVS_DEBUG_USE_FULL_SPEED)) { vdec_source_changed(VFORMAT_AVS, 4096, 2048, 60); } else { @@ -2177,6 +2422,9 @@ static void avs_set_clk(struct work_struct *work) } } +#ifdef DEBUG_MULTI_WITH_AUTOMODE +int delay_count = 0; +#endif static void vavs_put_timer_func(unsigned long arg) { struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_s *)arg; @@ -2185,11 +2433,17 @@ static void vavs_put_timer_func(unsigned long arg) #ifndef HANDLE_AVS_IRQ vavs_isr(); #endif - +#ifdef DEBUG_MULTI_WITH_AUTOMODE + if (delay_count > 0) { + if (delay_count == 1) + amvdec_start(); + delay_count--; + } +#endif if (READ_VREG(AVS_SOS_COUNT)) { if (!error_recovery_mode) { #if 0 - if (debug_flag & AVS_DEBUG_OLD_ERROR_HANDLE) { + if (debug & AVS_DEBUG_OLD_ERROR_HANDLE) { mutex_lock(&vavs_mutex); pr_info("vavs fatal error reset !\n"); amvdec_stop(); @@ -2263,14 +2517,14 @@ static void vavs_put_timer_func(unsigned long arg) struct vframe_s *vf; if (kfifo_get(&hw->recycle_q, &vf)) { - if ((vf->index < vf_buf_num) && + if ((vf->index < hw->vf_buf_num_used) && (--hw->vfbuf_use[vf->index] == 0)) { debug_print(hw, PRINT_FLAG_DECODING, "%s WRITE_VREG(AVS_BUFFERIN, 0x%x) for vf index of %d\n", __func__, ~(1 << vf->index), vf->index); WRITE_VREG(AVS_BUFFERIN, ~(1 << vf->index)); - vf->index = vf_buf_num; + vf->index = hw->vf_buf_num_used; } kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf); @@ -2440,7 +2694,7 @@ static s32 vavs_init(struct vdec_avs_hw_s *hw) if (size < 0) { amvdec_disable(); pr_err("get firmware fail."); - /*vfree(buf);*/ + vfree(fw); return -1; } @@ -2498,21 +2752,19 @@ static s32 vavs_init(struct vdec_avs_hw_s *hw) #endif hw->stat |= STAT_ISR_REG; - pr_info("%s %d\n", __func__, __LINE__); #ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER vf_provider_init(&vavs_vf_prov, PROVIDER_NAME, &vavs_vf_provider, hw); vf_reg_provider(&vavs_vf_prov); - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL); + avs_vf_notify_receiver(hw, PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL); #else vf_provider_init(&vavs_vf_prov, PROVIDER_NAME, &vavs_vf_provider, hw); vf_reg_provider(&vavs_vf_prov); #endif - pr_info("%s %d\n", __func__, __LINE__); if (hw->vavs_amstream_dec_info.rate != 0) { if (!hw->is_reset) - vf_notify_receiver(PROVIDER_NAME, + avs_vf_notify_receiver(hw, PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT, (void *)((unsigned long) hw->vavs_amstream_dec_info.rate)); @@ -2525,7 +2777,6 @@ static s32 vavs_init(struct vdec_avs_hw_s *hw) hw->recycle_timer.data = (ulong)(hw); hw->recycle_timer.function = vavs_put_timer_func; hw->recycle_timer.expires = jiffies + PUT_INTERVAL; - pr_info("%s %d\n", __func__, __LINE__); add_timer(&hw->recycle_timer); @@ -2537,10 +2788,15 @@ static s32 vavs_init(struct vdec_avs_hw_s *hw) #endif vdec_source_changed(VFORMAT_AVS, 1920, 1080, 30); +#ifdef DEBUG_MULTI_WITH_AUTOMODE + if (start_decoding_delay == 0) + amvdec_start(); + else + delay_count = start_decoding_delay/10; +#else amvdec_start(); - +#endif hw->stat |= STAT_VDEC_RUN; - pr_info("%s %d\n", __func__, __LINE__); return 0; } @@ -2569,7 +2825,9 @@ static int amvdec_avs_probe(struct platform_device *pdev) firmware_sel = 1; if (firmware_sel == 1) { +#ifndef USE_DYNAMIC_BUF_NUM vf_buf_num = 4; +#endif canvas_base = 0; canvas_num = 3; } else { @@ -2615,6 +2873,9 @@ static int amvdec_avs_probe(struct platform_device *pdev) kfree(hw->gvs); hw->gvs = NULL; pdata->dec_status = NULL; + if (hw->fw) + vfree(hw->fw); + hw->fw = NULL; return -ENODEV; } /*vdec = pdata;*/ @@ -2692,7 +2953,7 @@ static int amvdec_avs_remove(struct platform_device *pdev) #endif if (hw->stat & STAT_VF_HOOK) { if (hw->fr_hint_status == VDEC_HINTED && !hw->is_reset) - vf_notify_receiver(PROVIDER_NAME, + avs_vf_notify_receiver(hw, PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); hw->fr_hint_status = VDEC_NO_NEED_HINT; vf_unreg_provider(&vavs_vf_prov); @@ -2746,16 +3007,51 @@ static struct platform_driver amvdec_avs_driver = { } }; +static void recycle_frames(struct vdec_avs_hw_s *hw); static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) { struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_s *)vdec->private; int ret = 1; + unsigned buf_busy_mask = (1 << hw->vf_buf_num_used) - 1; +#ifdef DEBUG_MULTI_FRAME_INS + if ((DECODE_ID(hw) == 0) && run_count[0] > run_count[1] && + run_count[1] < max_run_count[1]) + return 0; + + if ((DECODE_ID(hw) == 1) && run_count[1] >= run_count[0] && + run_count[0] < max_run_count[0]) + return 0; - if ((hw->buf_status & 0xf) == 0xf && - kfifo_len(&hw->recycle_q) == 0) - ret = 0; + if (max_run_count[DECODE_ID(hw)] > 0 && + run_count[DECODE_ID(hw)] >= max_run_count[DECODE_ID(hw)]) + return 0; +#endif + + if (hw->reset_decode_flag == 0 && + hw->again_flag == 0 && + (hw->buf_status & buf_busy_mask) == buf_busy_mask) { + recycle_frames(hw); + if (hw->buf_recycle_status == 0) + ret = 0; + } + + if (again_threshold > 0 && + hw->pre_parser_wr_ptr != 0 && + hw->again_flag && + (!vdec_frame_based(vdec))) { + u32 parser_wr_ptr = + READ_PARSER_REG(PARSER_VIDEO_WP); + if (parser_wr_ptr >= hw->pre_parser_wr_ptr && + (parser_wr_ptr - hw->pre_parser_wr_ptr) < + again_threshold) { + int r = vdec_sync_input(vdec); + debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, + "%s buf lelvel:%x\n", __func__, r); + ret = 0; + } + } if (ret) hw->not_run_ready = 0; @@ -2788,6 +3084,9 @@ static void vavs_work(struct work_struct *work) hw->buf_recycle_status = 0; if (!hw->ctx_valid) hw->ctx_valid = 1; +#ifdef DEBUG_MULTI_FRAME_INS + msleep(delay); +#endif vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk); } else if (hw->dec_result == DEC_RESULT_AGAIN && (hw_to_vdec(hw)->next_status != @@ -2830,7 +3129,8 @@ static void vavs_work(struct work_struct *work) hw->stat &= ~STAT_ISR_REG; } } else if (hw->dec_result == DEC_RESULT_EOS) { - pr_info("%s: end of stream\n", __func__); + debug_print(hw, PRINT_FLAG_DECODING, + "%s: end of stream\n", __func__); if (hw->stat & STAT_VDEC_RUN) { amvdec_stop(); hw->stat &= ~STAT_VDEC_RUN; @@ -2890,14 +3190,35 @@ static void handle_decoding_error(struct vdec_avs_hw_s *hw) struct vframe_s *vf; spin_lock_irqsave(&lock, flags); for (i = 0; i < VF_POOL_SIZE; i++) { - vf = &hw->vfpool[i]; - if (vf->index < vf_buf_num) - vf->index = -1; + vf = &hw->vfpool[i].vf; + if (vf->index < hw->vf_buf_num_used) { + hw->vfpool[i].detached = 1; + hw->vfbuf_use[vf->index] = 0; + } } - for (i = 0; i < vf_buf_num; i++) - hw->vfbuf_use[i] = 0; + if (error_handle_policy & 0x2) { + while (!kfifo_is_empty(&hw->display_q)) { + if (kfifo_get(&hw->display_q, &vf)) { + if (buf_of_vf(vf)->detached !=0) { + debug_print(hw, PRINT_FLAG_DECODING, + "%s recycle %d => newframe_q\n", + __func__, + vf->index); + vf->index = hw->vf_buf_num_used; + buf_of_vf(vf)->detached = 0; + kfifo_put(&hw->newframe_q, + (const struct vframe_s *)vf); + } + } + + } + } + clear_pts_buf(hw); + hw->decode_pic_count = 0; hw->reset_decode_flag = 1; + hw->pre_parser_wr_ptr = 0; hw->buf_status = 0; + hw->throw_pb_flag = 1; spin_unlock_irqrestore(&lock, flags); } @@ -2905,13 +3226,20 @@ static void timeout_process(struct vdec_avs_hw_s *hw) { struct vdec_s *vdec = hw_to_vdec(hw); amvdec_stop(); - handle_decoding_error(hw); + if (error_handle_policy & 0x1) { + handle_decoding_error(hw); + } else { + vavs_save_regs(hw); + + if (hw->decode_pic_count == 0) + hw->decode_pic_count++; + } + hw->dec_result = DEC_RESULT_DONE; + debug_print(hw, PRINT_FLAG_ERROR, "%s decoder timeout, status=%d, level=%d\n", __func__, vdec->status, READ_VREG(VLD_MEM_VIFIFO_LEVEL)); - hw->dec_result = DEC_RESULT_DONE; reset_process_time(hw); - hw->first_i_frame_ready = 0; vdec_schedule_work(&hw->work); } @@ -2922,8 +3250,15 @@ static void recycle_frame_bufferin(struct vdec_avs_hw_s *hw) struct vframe_s *vf; if (kfifo_get(&hw->recycle_q, &vf)) { - if ((vf->index < vf_buf_num) && - (vf->index >= 0) && + if (buf_of_vf(vf)->detached) { + debug_print(hw, 0, + "%s recycle detached vf, index=%d detched %d used %d\n", + __func__, vf->index, + buf_of_vf(vf)->detached, + hw->vfbuf_use[vf->index]); + } + if ((vf->index < hw->vf_buf_num_used) && + (buf_of_vf(vf)->detached == 0) && (--hw->vfbuf_use[vf->index] == 0)) { hw->buf_recycle_status |= (1 << vf->index); WRITE_VREG(AVS_BUFFERIN, ~(1 << vf->index)); @@ -2933,7 +3268,8 @@ static void recycle_frame_bufferin(struct vdec_avs_hw_s *hw) READ_VREG(AVS_BUFFERIN), vf->index, hw->buf_recycle_status); } - vf->index = vf_buf_num; + vf->index = hw->vf_buf_num_used; + buf_of_vf(vf)->detached = 0; kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf); } @@ -2948,8 +3284,17 @@ static void recycle_frames(struct vdec_avs_hw_s *hw) struct vframe_s *vf; if (kfifo_get(&hw->recycle_q, &vf)) { - if ((vf->index < vf_buf_num) && - (vf->index >= 0) && + if (buf_of_vf(vf)->detached) { + debug_print(hw, 0, + "%s recycle detached vf, index=%d detched %d used %d\n", + __func__, vf->index, + buf_of_vf(vf)->detached, + hw->vfbuf_use[vf->index]); + } + + + if ((vf->index < hw->vf_buf_num_used) && + (buf_of_vf(vf)->detached == 0) && (--hw->vfbuf_use[vf->index] == 0)) { hw->buf_recycle_status |= (1 << vf->index); debug_print(hw, PRINT_FLAG_DECODING, @@ -2958,7 +3303,8 @@ static void recycle_frames(struct vdec_avs_hw_s *hw) vf->index, hw->buf_recycle_status); } - vf->index = vf_buf_num; + vf->index = hw->vf_buf_num_used; + buf_of_vf(vf)->detached = 0; kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf); } @@ -2976,7 +3322,7 @@ static void check_timer_func(unsigned long arg) unsigned long flags; if (hw->m_ins_flag && - (debug_flag & + (debug & DEBUG_WAIT_DECODE_DONE_WHEN_STOP) == 0 && vdec->next_status == VDEC_STATUS_DISCONNECTED) { @@ -2989,11 +3335,27 @@ static void check_timer_func(unsigned long arg) /*recycle*/ if (!hw->m_ins_flag || - hw->dec_result == DEC_RESULT_NONE) { + hw->dec_result == DEC_RESULT_NONE || + hw->dec_result == DEC_RESULT_USERDATA) { spin_lock_irqsave(&lock, flags); recycle_frame_bufferin(hw); spin_unlock_irqrestore(&lock, flags); } + + if (hw->m_ins_flag) { + if ((READ_VREG(AV_SCRATCH_5) & 0xf) != 0 && + (READ_VREG(AV_SCRATCH_5) & 0xff00) != 0){ + /*ucode buffer empty*/ + if ((kfifo_len(&hw->recycle_q) == 0) && + (kfifo_len(&hw->display_q) == 0)) { + debug_print(hw, + 0, "AV_SCRATCH_5=0x%x, recover ucode buffer_status\n", + READ_VREG(AV_SCRATCH_5)); + WRITE_VREG(AV_SCRATCH_5, 0x10); + /*let ucode to recover buffer_status*/ + } + } + } if (radr != 0) { if (rval != 0) { WRITE_VREG(radr, rval); @@ -3003,6 +3365,11 @@ static void check_timer_func(unsigned long arg) rval = 0; radr = 0; } + + if (udebug_flag != hw->old_udebug_flag) { + WRITE_VREG(DECODE_STOP_POS, udebug_flag); + hw->old_udebug_flag = udebug_flag; + } if (dbg_cmd != 0) { if (dbg_cmd == 1) { int r = vdec_sync_input(vdec); @@ -3018,9 +3385,7 @@ static void check_timer_func(unsigned long arg) } } - if ((debug_flag & DEBUG_FLAG_DISABLE_TIMEOUT) == 0 && - (input_frame_based(vdec) || - (READ_VREG(VLD_MEM_VIFIFO_LEVEL) > 0x100)) && + if ((debug & DEBUG_FLAG_DISABLE_TIMEOUT) == 0 && (timeout_val > 0) && (hw->start_process_time > 0) && ((1000 * (jiffies - hw->start_process_time) / HZ) @@ -3037,14 +3402,21 @@ static void check_timer_func(unsigned long arg) if (READ_VREG(AVS_SOS_COUNT)) { if (!error_recovery_mode) { amvdec_stop(); - handle_decoding_error(hw); + if (error_handle_policy & 0x1) { + handle_decoding_error(hw); + } else { + vavs_save_regs(hw); + + if (hw->decode_pic_count == 0) + hw->decode_pic_count++; + } + hw->dec_result = DEC_RESULT_DONE; + debug_print(hw, PRINT_FLAG_ERROR, "%s decoder error, status=%d, level=%d, AVS_SOS_COUNT=0x%x\n", __func__, vdec->status, READ_VREG(VLD_MEM_VIFIFO_LEVEL), READ_VREG(AVS_SOS_COUNT)); - hw->dec_result = DEC_RESULT_DONE; reset_process_time(hw); - hw->first_i_frame_ready = 0; vdec_schedule_work(&hw->work); } } @@ -3069,12 +3441,8 @@ static void check_timer_func(unsigned long arg) static int avs_hw_ctx_restore(struct vdec_avs_hw_s *hw) { /*int r = 0;*/ -#if DEBUG_MULTI_FLAG > 0 - if (hw->decode_pic_count > 0) - vavs_prot_init_vld_only(hw); - else -#endif vavs_prot_init(hw); + return 0; } @@ -3109,6 +3477,11 @@ void (*callback)(struct vdec_s *, void *), int save_reg = READ_VREG(POWER_CTL_VLD); int size, ret; /* reset everything except DOS_TOP[1] and APB_CBUS[0]*/ + + hw->pre_parser_wr_ptr = + READ_PARSER_REG(PARSER_VIDEO_WP); + +#if 1 #if DEBUG_MULTI_FLAG > 0 if (hw->decode_pic_count == 0) { #endif @@ -3116,10 +3489,14 @@ void (*callback)(struct vdec_s *, void *), WRITE_VREG(DOS_SW_RESET0, 0); WRITE_VREG(POWER_CTL_VLD, save_reg); hw->run_count++; + run_count[DECODE_ID(hw)] = hw->run_count; vdec_reset_core(vdec); #if DEBUG_MULTI_FLAG > 0 } #endif +#else + vdec_reset_core(vdec); +#endif hw->vdec_cb_arg = arg; hw->vdec_cb = callback; @@ -3155,7 +3532,7 @@ void (*callback)(struct vdec_s *, void *), data = ((u8 *)hw->chunk->block->start_virt) + hw->chunk->offset; - if (debug_flag & PRINT_FLAG_RUN_FLOW + if (debug & PRINT_FLAG_RUN_FLOW ) { debug_print(hw, 0, "%s decode_pic_count %d buf_recycle_status 0x%x: size 0x%x sum 0x%x %02x %02x %02x %02x %02x %02x .. %02x %02x %02x %02x\n", @@ -3167,7 +3544,7 @@ void (*callback)(struct vdec_s *, void *), data[size - 3], data[size - 2], data[size - 1]); } - if (debug_flag & PRINT_FRAMEBASE_DATA + if (debug & PRINT_FRAMEBASE_DATA ) { int jj; @@ -3205,7 +3582,10 @@ void (*callback)(struct vdec_s *, void *), hw->input_empty = 0; debug_print(hw, PRINT_FLAG_RUN_FLOW, "%s,%d, size=%d\n", __func__, __LINE__, size); - vdec_enable_input(vdec); + + /*vdec_enable_input(vdec); + need run after VC1_CONTROL_REG is configured + */ hw->init_flag = 1; if (hw->chunk) @@ -3233,7 +3613,6 @@ void (*callback)(struct vdec_s *, void *), vdec->mc_loaded = 1; vdec->mc_type = VFORMAT_AVS; } - if (avs_hw_ctx_restore(hw) < 0) { hw->dec_result = DEC_RESULT_ERROR; debug_print(hw, PRINT_FLAG_ERROR, @@ -3241,6 +3620,20 @@ void (*callback)(struct vdec_s *, void *), vdec_schedule_work(&hw->work); return; } + + /* + This configureation of VC1_CONTROL_REG will + pop bits (even no data in the stream buffer) if input is enabled, + so it can only be configured before vdec_enable_input() is called. + So move this code from ucode to here + */ +#define DISABLE_DBLK_HCMD 0 +#define DISABLE_MC_HCMD 0 + WRITE_VREG(VC1_CONTROL_REG, (DISABLE_DBLK_HCMD<<6) | + (DISABLE_MC_HCMD<<5) | (1 << 7) | (0xc <<8) | (1<<14)); + vdec_enable_input(vdec); + /**/ + /*wmb();*/ hw->stat |= STAT_MC_LOAD; hw->last_vld_level = 0; @@ -3249,18 +3642,24 @@ void (*callback)(struct vdec_s *, void *), "%s READ_VREG(AVS_BUFFERIN)=0x%x, recycle_q num %d\n", __func__, READ_VREG(AVS_BUFFERIN), kfifo_len(&hw->recycle_q)); - recycle_frames(hw); - if (hw->reset_decode_flag) { - hw->buf_recycle_status = 0xff; - WRITE_VREG(AVS_BUFFERIN, 0); - WRITE_VREG(AVS_BUFFEROUT, 0); + + WRITE_VREG(VIFF_BIT_CNT, size * 8); + if (hw->reset_decode_flag) + WRITE_VREG(DECODE_STATUS, 0); + else { + recycle_frames(hw); + avs_pts_check_in(hw, + hw->decode_pic_count & 0xffff, + hw->chunk); + + WRITE_VREG(DECODE_STATUS, + (hw->decode_pic_count & 0xffff) | + ((~hw->buf_recycle_status) << 16)); } - WRITE_VREG(DECODE_STATUS, - hw->decode_pic_count | - ((~hw->buf_recycle_status) << 24)); - hw->buf_recycle_status = 0; + if (hw->again_flag == 0) + hw->buf_recycle_status = 0; hw->reset_decode_flag = 0; - + hw->decode_status_skip_pic_done_flag = 0; start_process_time(hw); #if DEBUG_MULTI_FLAG == 1 if (hw->decode_pic_count > 0) @@ -3297,7 +3696,7 @@ static void vmavs_dump_state(struct vdec_s *vdec) { struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_s *)vdec->private; - + int i; debug_print(hw, 0, "====== %s\n", __func__); @@ -3309,11 +3708,12 @@ static void vmavs_dump_state(struct vdec_s *vdec) ); debug_print(hw, 0, - "is_framebase(%d), decode_status 0x%x, buf_status 0x%x, buf_recycle_status 0x%x, eos %d, state 0x%x, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d\n", + "is_framebase(%d), decode_status 0x%x, buf_status 0x%x, buf_recycle_status 0x%x, throw %d, eos %d, state 0x%x, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d\n", vdec_frame_based(vdec), READ_VREG(DECODE_STATUS) & 0xff, hw->buf_status, hw->buf_recycle_status, + hw->throw_pb_flag, hw->eos, hw->stat, hw->dec_result, @@ -3351,6 +3751,11 @@ static void vmavs_dump_state(struct vdec_s *vdec) hw->put_num ); + debug_print(hw, 0, "vfbuf_use:\n"); + for (i = 0; i < hw->vf_buf_num_used; i++) + debug_print(hw, 0, "%d: vf_buf_use %d\n", + i, hw->vfbuf_use[i]); + debug_print(hw, 0, "DECODE_STATUS=0x%x\n", READ_VREG(DECODE_STATUS)); @@ -3361,6 +3766,9 @@ static void vmavs_dump_state(struct vdec_s *vdec) "DECODE_MODE=0x%x\n", READ_VREG(DECODE_MODE)); debug_print(hw, 0, + "wait_buf_status, AV_SCRATCH_5=0x%x\n", + READ_VREG(AV_SCRATCH_5)); + debug_print(hw, 0, "MBY_MBX=0x%x\n", READ_VREG(MBY_MBX)); debug_print(hw, 0, @@ -3421,7 +3829,534 @@ static void vmavs_dump_state(struct vdec_s *vdec) } -static int ammvdec_avs_probe(struct platform_device *pdev) + int ammvdec_avs_probe(struct platform_device *pdev) +{ + struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; + struct vdec_avs_hw_s *hw = NULL; + + if (vdec_get_debug_flags() & 0x8) + return amvdec_avs_probe(pdev); + + pr_info("ammvdec_avs probe start.\n"); + + if (pdata == NULL) { + pr_info("ammvdec_avs platform data undefined.\n"); + return -EFAULT; + } + + hw = (struct vdec_avs_hw_s *)devm_kzalloc(&pdev->dev, + sizeof(struct vdec_avs_hw_s), GFP_KERNEL); + if (hw == NULL) { + pr_info("\nammvdec_avs decoder driver alloc failed\n"); + return -ENOMEM; + } + /*atomic_set(&hw->error_handler_run, 0);*/ + hw->m_ins_flag = 1; + + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM || disable_longcabac_trans) + firmware_sel = 1; + + if (firmware_sel == 1) { +#ifndef USE_DYNAMIC_BUF_NUM + vf_buf_num = 4; +#endif + canvas_base = 0; + canvas_num = 3; + } else { + pr_info("Error, do not support longcabac work around!!!"); + return -ENOMEM; + } + + if (pdata->sys_info) + hw->vavs_amstream_dec_info = *pdata->sys_info; + + hw->is_reset = 0; + pdata->user_data_read = NULL; + pdata->reset_userdata_fifo = NULL; + + pdata->private = hw; + pdata->dec_status = vavs_dec_status; + pdata->set_isreset = vavs_set_isreset; + pdata->run_ready = run_ready; + pdata->run = run; + pdata->reset = reset; + pdata->irq_handler = vmavs_isr; + pdata->threaded_irq_handler = vmavs_isr_thread_fn; + pdata->dump_state = vmavs_dump_state; + + vavs_vdec_info_init(hw); + +#ifdef ENABLE_USER_DATA + if (NULL == hw->user_data_buffer) { + hw->user_data_buffer = + dma_alloc_coherent(amports_get_dma_device(), + USER_DATA_SIZE, + &hw->user_data_buffer_phys, GFP_KERNEL); + if (!hw->user_data_buffer) { + pr_info("%s: Can not allocate hw->user_data_buffer\n", + __func__); + return -ENOMEM; + } + pr_debug("hw->user_data_buffer = 0x%p, hw->user_data_buffer_phys = 0x%x\n", + hw->user_data_buffer, (u32)hw->user_data_buffer_phys); + } +#endif + hw->lmem_addr = kmalloc(LMEM_BUF_SIZE, GFP_KERNEL); + if (hw->lmem_addr == NULL) { + pr_err("%s: failed to alloc lmem buffer\n", __func__); + return -1; + } + hw->lmem_phy_addr = dma_map_single(amports_get_dma_device(), + hw->lmem_addr, LMEM_BUF_SIZE, DMA_FROM_DEVICE); + if (dma_mapping_error(amports_get_dma_device(), + hw->lmem_phy_addr)) { + pr_err("%s: failed to map lmem buffer\n", __func__); + kfree(hw->lmem_addr); + hw->lmem_addr = NULL; + return -1; + } + + /*INIT_WORK(&hw->set_clk_work, avs_set_clk);*/ + + if (vavs_init(hw) < 0) { + pr_info("amvdec_avs init failed.\n"); + kfree(hw->gvs); + hw->gvs = NULL; + pdata->dec_status = NULL; + return -ENODEV; + } + + /*INIT_WORK(&hw->fatal_error_wd_work, vavs_fatal_error_handler); + atomic_set(&hw->error_handler_run, 0);*/ +#if 0 +#ifdef ENABLE_USER_DATA + INIT_WORK(&hw->userdata_push_work, userdata_push_do_work); +#endif +#endif + INIT_WORK(&hw->notify_work, vavs_notify_work); + + if (pdata->use_vfm_path) { + snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, + VFM_DEC_PROVIDER_NAME); + hw->frameinfo_enable = 1; + } + else + snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, + MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff); + if (pdata->parallel_dec == 1) { + int i; + for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) + hw->canvas_spec[i] = 0xffffff; + } + vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, + &vavs_vf_provider, hw); + + platform_set_drvdata(pdev, pdata); + + hw->platform_dev = pdev; + + vdec_set_prepare_level(pdata, start_decode_buf_level); + + vdec_set_vframe_comm(pdata, DRIVER_NAME); + + if (pdata->parallel_dec == 1) + vdec_core_request(pdata, CORE_MASK_VDEC_1); + else { + vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC + | CORE_MASK_COMBINE); + } + + /*INIT_WORK(&hw->userdata_push_work, userdata_push_do_work);*/ + + + return 0; +} + + int ammvdec_avs_remove(struct platform_device *pdev) +{ + + if (vdec_get_debug_flags() & 0x8) + return amvdec_avs_remove(pdev); + else { + struct vdec_avs_hw_s *hw = + (struct vdec_avs_hw_s *) + (((struct vdec_s *)(platform_get_drvdata(pdev)))->private); + struct vdec_s *vdec = hw_to_vdec(hw); + int i; + + if (hw->stat & STAT_VDEC_RUN) { + amvdec_stop(); + hw->stat &= ~STAT_VDEC_RUN; + } + + if (hw->stat & STAT_ISR_REG) { + vdec_free_irq(VDEC_IRQ_1, (void *)hw); + hw->stat &= ~STAT_ISR_REG; + } + + if (hw->stat & STAT_TIMER_ARM) { + del_timer_sync(&hw->check_timer); + hw->stat &= ~STAT_TIMER_ARM; + } + + cancel_work_sync(&hw->work); + cancel_work_sync(&hw->notify_work); + + if (hw->mm_blk_handle) { + decoder_bmmu_box_free(hw->mm_blk_handle); + hw->mm_blk_handle = NULL; + } + if (vdec->parallel_dec == 1) + vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1); + else + vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1 | CORE_MASK_HEVC); + vdec_set_status(hw_to_vdec(hw), VDEC_STATUS_DISCONNECTED); + + if (vdec->parallel_dec == 1) { + for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { + vdec->free_canvas_ex(canvas_y(hw->canvas_spec[i]), vdec->id); + vdec->free_canvas_ex(canvas_u(hw->canvas_spec[i]), vdec->id); + } + } + #ifdef ENABLE_USER_DATA + if (hw->user_data_buffer != NULL) { + dma_free_coherent( + amports_get_dma_device(), + USER_DATA_SIZE, + hw->user_data_buffer, + hw->user_data_buffer_phys); + hw->user_data_buffer = NULL; + hw->user_data_buffer_phys = 0; + } + #endif + if (hw->lmem_addr) { + dma_unmap_single(amports_get_dma_device(), + hw->lmem_phy_addr, LMEM_BUF_SIZE, DMA_FROM_DEVICE); + kfree(hw->lmem_addr); + hw->lmem_addr = NULL; + } + + if (hw->fw) { + vfree(hw->fw); + hw->fw = NULL; + } + + pr_info("ammvdec_avs removed.\n"); + if (hw->gvs) { + kfree(hw->gvs); + hw->gvs = NULL; + } + + return 0; + } +} + + +#ifdef DEBUG_MULTI_WITH_AUTOMODE +struct stream_buf_s *get_vbuf(void); +s32 esparser_init(struct stream_buf_s *buf, struct vdec_s *vdec); + + +static s32 vavs_init2(struct vdec_avs_hw_s *hw) +{ + int size = -1; + struct firmware_s *fw; + u32 fw_size = 0x1000 * 16; + + fw = vmalloc(sizeof(struct firmware_s) + fw_size); + if (IS_ERR_OR_NULL(fw)) + return -ENOMEM; + + pr_info("vavs_init\n"); + + amvdec_enable(); + + + vavs_local_init(hw); + + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM) + size = get_firmware_data(VIDEO_DEC_AVS_MULTI, fw->data); + else { + if (firmware_sel == 1) + size = get_firmware_data(VIDEO_DEC_AVS_NOCABAC, fw->data); +#ifdef AVSP_LONG_CABAC + else { + init_avsp_long_cabac_buf(); + size = get_firmware_data(VIDEO_DEC_AVS_MULTI, fw->data); + } +#endif + } + + if (size < 0) { + amvdec_disable(); + pr_err("get firmware fail."); + /*vfree(buf);*/ + return -1; + } + + fw->len = size; + hw->fw = fw; + if (hw->m_ins_flag) { + init_timer(&hw->check_timer); + hw->check_timer.data = (ulong) hw; + hw->check_timer.function = check_timer_func; + hw->check_timer.expires = jiffies + CHECK_INTERVAL; + + + //add_timer(&hw->check_timer); + hw->stat |= STAT_TIMER_ARM; + + INIT_WORK(&hw->work, vavs_work); + + hw->fw = fw; + } + return 0; +} + +unsigned int debug_flag2; +static int vavs_prot_init2(struct vdec_avs_hw_s *hw, unsigned char post_flag) +{ + int r = 0; + /* + * 2: assist + * 3: vld_reset + * 4: vld_part_reset + * 5: vfifo reset + * 6: iqidct + * 7: mc + * 8: dblk + * 9: pic_dc + * 10: psc + * 11: mcpu + * 12: ccpu + * 13: ddr + * 14: afifo + */ + unsigned char run_flag; +#ifdef OOO + WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) /*| (1 << 4)*/); + WRITE_VREG(DOS_SW_RESET0, 0); + + READ_VREG(DOS_SW_RESET0); + + WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) /*| (1 << 4)*/); + WRITE_VREG(DOS_SW_RESET0, 0); + + WRITE_VREG(DOS_SW_RESET0, (1 << 9) | (1 << 8)); + WRITE_VREG(DOS_SW_RESET0, 0); +#endif + /***************** reset vld **********************************/ +#ifdef OOO + WRITE_VREG(POWER_CTL_VLD, 0x10); + WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 2, MEM_FIFO_CNT_BIT, 2); + WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 8, MEM_LEVEL_CNT_BIT, 6); +#endif + if (start_decoding_delay & 0x80000) + msleep(start_decoding_delay&0xffff); + +if (debug_flag2 & 0x1) + run_flag = post_flag; +else + run_flag = !post_flag; +if (run_flag) { + if (hw->m_ins_flag) { + int i; + if (hw->decode_pic_count == 0) { + r = vavs_canvas_init(hw); +#ifndef USE_DYNAMIC_BUF_NUM + for (i = 0; i < 4; i++) { + WRITE_VREG(AV_SCRATCH_0 + i, + hw->canvas_spec[i] + ); + } +#else + for (i = 0; i < hw->vf_buf_num_used; i += 2) { + WRITE_VREG(buf_spec_reg[i >> 1], + (hw->canvas_spec[i] & 0xffff) | + ((hw->canvas_spec[i + 1] & 0xffff) + << 16) + ); + } +#endif + } else + vavs_restore_regs(hw); + + for (i = 0; i < hw->vf_buf_num_used; i++) { + canvas_config_ex(canvas_y(hw->canvas_spec[i]), + hw->canvas_config[i][0].phy_addr, + hw->canvas_config[i][0].width, + hw->canvas_config[i][0].height, + CANVAS_ADDR_NOWRAP, + hw->canvas_config[i][0].block_mode, + 0); + + canvas_config_ex(canvas_u(hw->canvas_spec[i]), + hw->canvas_config[i][1].phy_addr, + hw->canvas_config[i][1].width, + hw->canvas_config[i][1].height, + CANVAS_ADDR_NOWRAP, + hw->canvas_config[i][1].block_mode, + 0); + } + } +} + +if (debug_flag2 & 0x2) + run_flag = post_flag; +else + run_flag = !post_flag; +if (run_flag) { + + /* notify ucode the buffer offset */ + if (hw->decode_pic_count == 0) + WRITE_VREG(AV_SCRATCH_F, hw->buf_offset); +#ifdef OOO + /* disable PSCALE for hardware sharing */ + WRITE_VREG(PSCALE_CTRL, 0); +#endif + } + if (start_decoding_delay & 0x40000) + msleep(start_decoding_delay&0xffff); + + if (debug_flag2 & 0x4) + run_flag = post_flag; + else + run_flag = !post_flag; + if (run_flag) { + if (hw->decode_pic_count == 0) { +#ifndef USE_DYNAMIC_BUF_NUM + WRITE_VREG(AVS_SOS_COUNT, 0); +#endif + WRITE_VREG(AVS_BUFFERIN, 0); + WRITE_VREG(AVS_BUFFEROUT, 0); + } + if (error_recovery_mode) + WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 0); + else + WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 1); + /* clear mailbox interrupt */ + WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); + + /* enable mailbox interrupt */ + WRITE_VREG(ASSIST_MBOX1_MASK, 1); +} + +if (debug_flag2 & 0x8) + run_flag = post_flag; +else + run_flag = !post_flag; +if (run_flag) { + +#ifndef USE_DYNAMIC_BUF_NUM /* def DEBUG_UCODE */ + if (hw->decode_pic_count == 0) + WRITE_VREG(AV_SCRATCH_D, 0); +#endif + if (start_decoding_delay & 0x10000) + msleep(start_decoding_delay&0xffff); +#ifdef NV21 + SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); +#endif + if (start_decoding_delay & 0x20000) + msleep(start_decoding_delay&0xffff); + + +#ifdef PIC_DC_NEED_CLEAR + CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31); +#endif +} +if (debug_flag2 & 0x10) + run_flag = post_flag; +else + run_flag = !post_flag; +if (run_flag) { +#ifdef ENABLE_USER_DATA + if (firmware_sel == 0) { + pr_info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! firmware_sel is 0\n"); + WRITE_VREG(AV_SCRATCH_N, (u32)(hw->user_data_buffer_phys - hw->buf_offset)); + pr_debug("AV_SCRATCH_N = 0x%x\n", READ_VREG(AV_SCRATCH_N)); + } +#endif +} + +if (debug_flag2 & 0x20) + run_flag = post_flag; +else + run_flag = !post_flag; +if (run_flag) { + if (hw->m_ins_flag) { + if (vdec_frame_based(hw_to_vdec(hw))) + WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_FRAMEBASE); + else + WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE); + WRITE_VREG(DECODE_LMEM_BUF_ADR, hw->lmem_phy_addr); + } else + WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE); + WRITE_VREG(DECODE_STOP_POS, udebug_flag); + hw->old_udebug_flag = udebug_flag; +} + return r; +} + +static void init_hw(struct vdec_s *vdec) +{ + struct vdec_avs_hw_s *hw = + (struct vdec_avs_hw_s *)vdec->private; + int ret; + pr_info("%s, %d\n", __func__, __LINE__); + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM) + ret = amvdec_loadmc_ex(VFORMAT_AVS, NULL, hw->fw->data); + else if (firmware_sel == 1) + ret = amvdec_loadmc_ex(VFORMAT_AVS, "avs_no_cabac", hw->fw->data); + else + ret = amvdec_loadmc_ex(VFORMAT_AVS, NULL, hw->fw->data); + + if (ret < 0) { + amvdec_disable(); + /*vfree(buf);*/ + pr_err("AVS: the %s fw loading failed, err: %x\n", + tee_enabled() ? "TEE" : "local", ret); + } + pr_info("%s, %d\n", __func__, __LINE__); + + /*vfree(buf);*/ + + hw->stat |= STAT_MC_LOAD; + + /* enable AMRISC side protocol */ + ret = vavs_prot_init2(hw, 0); + if (ret < 0) + return; + pr_info("%s, %d\n", __func__, __LINE__); + +} + + +static unsigned long run_ready2(struct vdec_s *vdec, unsigned long mask) +{ + return 1; +} + +static void run2(struct vdec_s *vdec, unsigned long mask, +void (*callback)(struct vdec_s *, void *), + void *arg) +{ + struct vdec_avs_hw_s *hw = + (struct vdec_avs_hw_s *)vdec->private; + pr_info("%s, %d\n", __func__, __LINE__); + + vavs_prot_init2(hw, 1); + + vdec_source_changed(VFORMAT_AVS, + 1920, 1080, 30); + + amvdec_start(); + + hw->stat |= STAT_VDEC_RUN; + pr_info("%s %d\n", __func__, __LINE__); + +} + +static int ammvdec_avs_probe2(struct platform_device *pdev) { struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; struct vdec_avs_hw_s *hw = NULL; @@ -3450,7 +4385,9 @@ static int ammvdec_avs_probe(struct platform_device *pdev) pr_info("%s %d\n", __func__, __LINE__); if (firmware_sel == 1) { +#ifndef USE_DYNAMIC_BUF_NUM vf_buf_num = 4; +#endif canvas_base = 0; canvas_num = 3; } else { @@ -3472,8 +4409,8 @@ static int ammvdec_avs_probe(struct platform_device *pdev) pdata->private = hw; pdata->dec_status = vavs_dec_status; pdata->set_isreset = vavs_set_isreset; - pdata->run_ready = run_ready; - pdata->run = run; + pdata->run_ready = run_ready2; + pdata->run = run2; pdata->reset = reset; pdata->irq_handler = vmavs_isr; pdata->threaded_irq_handler = vmavs_isr_thread_fn; @@ -3521,23 +4458,19 @@ static int ammvdec_avs_probe(struct platform_device *pdev) pr_info("%s %d\n", __func__, __LINE__); - if (vavs_init(hw) < 0) { + if (vavs_init2(hw) < 0) { pr_info("amvdec_avs init failed.\n"); kfree(hw->gvs); hw->gvs = NULL; pdata->dec_status = NULL; return -ENODEV; } + /*vdec = pdata;*/ + pr_info("%s, %d\n", __func__, __LINE__); - /*INIT_WORK(&hw->fatal_error_wd_work, vavs_fatal_error_handler); - atomic_set(&hw->error_handler_run, 0);*/ -#if 0 -#ifdef ENABLE_USER_DATA - INIT_WORK(&hw->userdata_push_work, userdata_push_do_work); -#endif -#endif +if (hw->m_ins_flag) { INIT_WORK(&hw->notify_work, vavs_notify_work); - +#if 1 if (pdata->use_vfm_path) { snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, VFM_DEC_PROVIDER_NAME); @@ -3566,53 +4499,91 @@ static int ammvdec_avs_probe(struct platform_device *pdev) vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC | CORE_MASK_COMBINE); } + pr_info("%s, %d\n", __func__, __LINE__); +#endif +}else{ + /*INIT_WORK(&hw->fatal_error_wd_work, vavs_fatal_error_handler); + atomic_set(&hw->error_handler_run, 0);*/ +#ifdef ENABLE_USER_DATA + INIT_WORK(&hw->userdata_push_work, userdata_push_do_work); +#endif + INIT_WORK(&hw->notify_work, vavs_notify_work); +} - /*INIT_WORK(&hw->userdata_push_work, userdata_push_do_work);*/ + init_hw(pdata); return 0; } -static int ammvdec_avs_remove(struct platform_device *pdev) +static int ammvdec_avs_remove2(struct platform_device *pdev) { - struct vdec_avs_hw_s *hw = - (struct vdec_avs_hw_s *) - (((struct vdec_s *)(platform_get_drvdata(pdev)))->private); - struct vdec_s *vdec = hw_to_vdec(hw); - int i; + struct vdec_avs_hw_s *hw = ghw; + cancel_work_sync(&hw->fatal_error_wd_work); + atomic_set(&hw->error_handler_run, 0); +#ifdef ENABLE_USER_DATA + cancel_work_sync(&hw->userdata_push_work); +#endif + cancel_work_sync(&hw->notify_work); + cancel_work_sync(&hw->set_clk_work); if (hw->stat & STAT_VDEC_RUN) { amvdec_stop(); hw->stat &= ~STAT_VDEC_RUN; } if (hw->stat & STAT_ISR_REG) { - vdec_free_irq(VDEC_IRQ_1, (void *)hw); + vdec_free_irq(VDEC_IRQ_1, (void *)vavs_dec_id); hw->stat &= ~STAT_ISR_REG; } if (hw->stat & STAT_TIMER_ARM) { - del_timer_sync(&hw->check_timer); + del_timer_sync(&hw->recycle_timer); hw->stat &= ~STAT_TIMER_ARM; } +#ifdef AVSP_LONG_CABAC + if (firmware_sel == 0) { + mutex_lock(&vavs_mutex); + cancel_work_sync(&long_cabac_wd_work); + mutex_unlock(&vavs_mutex); - cancel_work_sync(&hw->work); - cancel_work_sync(&hw->notify_work); - - if (hw->mm_blk_handle) { - decoder_bmmu_box_free(hw->mm_blk_handle); - hw->mm_blk_handle = NULL; - } - if (vdec->parallel_dec == 1) - vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1); - else - vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1 | CORE_MASK_HEVC); - vdec_set_status(hw_to_vdec(hw), VDEC_STATUS_DISCONNECTED); + if (es_write_addr_virt) { +#if 0 + codec_mm_free_for_dma("vavs", es_write_addr_phy); +#else + dma_unmap_single(amports_get_dma_device(), + es_write_addr_phy, + MAX_CODED_FRAME_SIZE, DMA_FROM_DEVICE); + /*kfree(es_write_addr_virt);*/ + es_write_addr_virt = NULL; +#endif + } - if (vdec->parallel_dec == 1) { - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { - vdec->free_canvas_ex(canvas_y(hw->canvas_spec[i]), vdec->id); - vdec->free_canvas_ex(canvas_u(hw->canvas_spec[i]), vdec->id); +#ifdef BITSTREAM_READ_TMP_NO_CACHE + if (bitstream_read_tmp) { + dma_free_coherent(amports_get_dma_device(), + SVA_STREAM_BUF_SIZE, bitstream_read_tmp, + bitstream_read_tmp_phy); + bitstream_read_tmp = NULL; + } +#else + if (bitstream_read_tmp) { + dma_unmap_single(amports_get_dma_device(), + bitstream_read_tmp_phy, + SVA_STREAM_BUF_SIZE, DMA_FROM_DEVICE); + kfree(bitstream_read_tmp); + bitstream_read_tmp = NULL; } +#endif } +#endif + if (hw->stat & STAT_VF_HOOK) { + if (hw->fr_hint_status == VDEC_HINTED && !hw->is_reset) + avs_vf_notify_receiver(hw, PROVIDER_NAME, + VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); + hw->fr_hint_status = VDEC_NO_NEED_HINT; + vf_unreg_provider(&vavs_vf_prov); + hw->stat &= ~STAT_VF_HOOK; + } + #ifdef ENABLE_USER_DATA if (hw->user_data_buffer != NULL) { dma_free_coherent( @@ -3624,31 +4595,41 @@ static int ammvdec_avs_remove(struct platform_device *pdev) hw->user_data_buffer_phys = 0; } #endif - if (hw->lmem_addr) { - dma_unmap_single(amports_get_dma_device(), - hw->lmem_phy_addr, LMEM_BUF_SIZE, DMA_FROM_DEVICE); - kfree(hw->lmem_addr); - hw->lmem_addr = NULL; - } if (hw->fw) { vfree(hw->fw); hw->fw = NULL; } - pr_info("ammvdec_avs removed.\n"); - if (hw->gvs) { - kfree(hw->gvs); - hw->gvs = NULL; + amvdec_disable(); + /*vdec_disable_DMC(NULL);*/ + + hw->pic_type = 0; + if (hw->mm_blk_handle) { + decoder_bmmu_box_free(hw->mm_blk_handle); + hw->mm_blk_handle = NULL; } +#ifdef DEBUG_PTS + pr_debug("pts hit %d, pts missed %d, i hit %d, missed %d\n", hw->pts_hit, + hw->pts_missed, hw->pts_i_hit, hw->pts_i_missed); + pr_debug("total frame %d, hw->avi_flag %d, rate %d\n", hw->total_frame, hw->avi_flag, + hw->vavs_amstream_dec_info.rate); +#endif + kfree(hw->gvs); + hw->gvs = NULL; return 0; } - +#endif static struct platform_driver ammvdec_avs_driver = { +#ifdef DEBUG_MULTI_WITH_AUTOMODE + .probe = ammvdec_avs_probe2, + .remove = ammvdec_avs_remove2, +#else .probe = ammvdec_avs_probe, .remove = ammvdec_avs_remove, +#endif #ifdef CONFIG_PM .suspend = amvdec_suspend, .resume = amvdec_resume, @@ -3684,12 +4665,14 @@ static int __init ammvdec_avs_driver_init_module(void) if (platform_driver_register(&ammvdec_avs_driver)) pr_err("failed to register ammvdec_avs driver\n"); - - /*if (platform_driver_register(&amvdec_avs_driver)) { +#ifdef DEBUG_WITH_SINGLE_MODE + if (platform_driver_register(&amvdec_avs_driver)) { pr_info("failed to register amvdec_avs driver\n"); return -ENODEV; - }*/ + } +#else amvdec_avs_driver = amvdec_avs_driver; +#endif if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB) ammvdec_avs_profile.profile = "avs+"; @@ -3706,8 +4689,9 @@ static void __exit ammvdec_avs_driver_remove_module(void) pr_debug("ammvdec_avs module remove.\n"); platform_driver_unregister(&ammvdec_avs_driver); - - /*platform_driver_unregister(&amvdec_avs_driver);*/ +#ifdef DEBUG_WITH_SINGLE_MODE + platform_driver_unregister(&amvdec_avs_driver); +#endif } /****************************************/ @@ -3726,8 +4710,8 @@ MODULE_PARM_DESC(stat, "\n amvdec_avs stat\n"); module_param(step, uint, 0664); MODULE_PARM_DESC(step, "\n step\n"); -module_param(debug_flag, uint, 0664); -MODULE_PARM_DESC(debug_flag, "\n debug_flag\n"); +module_param(debug, uint, 0664); +MODULE_PARM_DESC(debug, "\n debug\n"); module_param(debug_mask, uint, 0664); MODULE_PARM_DESC(debug_mask, "\n debug_mask\n"); @@ -3785,6 +4769,13 @@ module_param(decode_timeout_val, uint, 0664); MODULE_PARM_DESC(decode_timeout_val, "\n avs decode_timeout_val\n"); +module_param(error_handle_policy, uint, 0664); +MODULE_PARM_DESC(error_handle_policy, + "\n avs error_handle_policy\n"); + +module_param(again_threshold, uint, 0664); +MODULE_PARM_DESC(again_threshold, "\n again_threshold\n"); + module_param(udebug_flag, uint, 0664); MODULE_PARM_DESC(udebug_flag, "\n amvdec_h265 udebug_flag\n"); @@ -3797,11 +4788,33 @@ MODULE_PARM_DESC(udebug_pause_val, "\n udebug_pause_val\n"); module_param(udebug_pause_decode_idx, uint, 0664); MODULE_PARM_DESC(udebug_pause_decode_idx, "\n udebug_pause_decode_idx\n"); +module_param(udebug_pause_ins_id, uint, 0664); +MODULE_PARM_DESC(udebug_pause_ins_id, "\n udebug_pause_ins_id\n"); + +module_param(start_decoding_delay, uint, 0664); +MODULE_PARM_DESC(start_decoding_delay, "\n start_decoding_delay\n"); + +#ifdef DEBUG_MULTI_WITH_AUTOMODE +module_param(debug_flag2, uint, 0664); +MODULE_PARM_DESC(debug_flag2, "\n debug_flag2\n"); +#endif module_param(force_fps, uint, 0664); MODULE_PARM_DESC(force_fps, "\n force_fps\n"); +#ifdef DEBUG_MULTI_FRAME_INS +module_param(delay, uint, 0664); +MODULE_PARM_DESC(delay, "\n delay\n"); + +module_param_array(max_run_count, uint, &max_decode_instance_num, 0664); + +#endif + +module_param_array(ins_udebug_flag, uint, &max_decode_instance_num, 0664); + module_param_array(max_process_time, uint, &max_decode_instance_num, 0664); +module_param_array(run_count, uint, &max_decode_instance_num, 0664); + module_param_array(max_get_frame_interval, uint, &max_decode_instance_num, 0664); |